rm(list=ls(all=TRUE))
library(tidyverse)
Warning: package ‘tidyverse’ was built under R version 4.1.3Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
-- Attaching packages ----------------------------------------------------------------------------------------------------------------- tidyverse 1.3.2 --
√ ggplot2 3.3.5     √ purrr   0.3.4
√ tibble  3.1.6     √ dplyr   1.0.7
√ tidyr   1.1.4     √ stringr 1.4.0
√ readr   2.1.1     √ forcats 0.5.1
-- Conflicts -------------------------------------------------------------------------------------------------------------------- tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(magrittr)

Attaching package: ‘magrittr’

The following object is masked from ‘package:purrr’:

    set_names

The following object is masked from ‘package:tidyr’:

    extract
library(jsonlite)

Attaching package: ‘jsonlite’

The following object is masked from ‘package:purrr’:

    flatten
library(broom)

Read example json file:

results_dir <- "microbeMASST_results/"
json_example <- read_json(str_c(results_dir, "fastMASST_HILIC_neg__165_microbe.json"), simplifyVector = F)

Define function for iterating over nodes in the MASST output:

iterate_masst <- function(masst_node){
  node_attributes <- names(masst_node)
  if ("Rank" %in% node_attributes && masst_node$Rank == "phylum") {
    tibble(
      NAME = masst_node$name, 
      TYPE = masst_node$type, 
      NCBI = masst_node$NCBI, 
      RANK = masst_node$Rank, 
      GROUP_SIZE = masst_node$group_size, 
      MATCHED_SIZE = masst_node$matched_size
      )
  }
  else {
    if ("type" %in% node_attributes && masst_node$type == "node") {
      lapply(masst_node$children, iterate_masst) %>% 
        bind_rows()
    }
    else {
      tibble(
        NAME = character(), 
        TYPE = character(), 
        NCBI = character(), 
        RANK = character(), 
        GROUP_SIZE = integer(), 
        MATCHED_SIZE = integer()
        )
    }
  }
}

iterate_masst(json_example)

Set up tibble initialized with all json file names:

masst_results <- tibble(FILE_NAME = dir(results_dir, ".*\\.json"))

masst_results

Parse info from file names:

masst_results <- masst_results %>% 
  mutate(
    SEARCH_TYPE = FILE_NAME %>% str_extract("food|microbe"),
    DATASET = FILE_NAME %>% str_extract("(HILIC|RP).+(pos|neg)"),
    DATASET = if_else(DATASET == "RP_neg", "RP18_neg", DATASET),
    SCAN = FILE_NAME %>% str_extract("__.+_") %>% str_extract("[0-9]+"),
    FEATURE_ID = str_c(
      case_when(
        DATASET == "RP18_pos"  ~ "X94",
        DATASET == "RP18_neg"  ~ "X95",
        DATASET == "HILIC_pos" ~ "X96",
        DATASET == "HILIC_neg" ~ "X97"
      ),
      SCAN %>% str_pad(max(nchar(SCAN)), "left", "0")
    )
  )

masst_results

Number of results files per dataset:

masst_results %>% 
  count(DATASET)

Read json files for microbeMASST:

masst_results <- masst_results %>% 
  mutate(
    PATH = str_c(results_dir, FILE_NAME),
    JSON = PATH %>% map(read_json),
    STATS_PHYLUM = JSON %>% map(iterate_masst)
  )

masst_results$JSON[[1]][setdiff(names(masst_results$JSON[[1]]), c("children", "pie_data"))]
$name
[1] "root"

$duplication
[1] "Y"

$type
[1] "node"

$NCBI
[1] "131567"

$Rank
[1] "cellular organisms"

$group_size
[1] 72560

$matched_size
[1] 3

$occurrence_fraction
[1] 4.134509e-05

Add stats for phylum:

masst_results <- masst_results %>% 
  mutate(
    STATS_ROOT   = JSON %>% map(~ tibble(ROOT_GROUP_SIZE = .$group_size, ROOT_MATCHED_SIZE = .$matched_size)),
    STATS_PHYLUM = JSON %>% map(iterate_masst)
  )

masst_results$STATS_ROOT[[1]]
masst_results$STATS_PHYLUM[[1]]

Select relevant columns and unnest stats:

masst_results <- masst_results %>% 
  select(FEATURE_ID, DATASET, SEARCH_TYPE, STATS_ROOT, STATS_PHYLUM) %>% 
  unnest(c(STATS_ROOT, STATS_PHYLUM))

masst_results

Check: Is there any other TYPE than “node”?

masst_results$TYPE %>% unique()
[1] "node"

Check: Is there any other RANK than “phylum”?

masst_results$RANK %>% unique()
[1] "phylum"

Perform Fisher’s exact test for the association between features and phyla:

masst_results <- masst_results %>% 
  filter(MATCHED_SIZE > 0) %>% 
  mutate(
    FISHER = pmap(
      list(
        ROOT_GROUP_SIZE, 
        ROOT_MATCHED_SIZE, 
        GROUP_SIZE, 
        MATCHED_SIZE
      ),
      ~ fisher.test(
        matrix(
          c(..1, ..2, ..3, ..4),
          nrow = 2
        )
      )
    ),
    FISHER = FISHER %>% map(tidy)
  ) %>% 
  unnest(FISHER)

masst_results

Perform correction for multiple testing and check distribution of p-values:

masst_results <- masst_results %>% 
  mutate(p.value.fdr = p.value %>% p.adjust(method = "fdr"))

masst_results %>% 
  ggplot() + 
  geom_point(aes(p.value, p.value.fdr)) +
  geom_abline(slope = 1)


masst_results %>% 
  ggplot() +
  geom_histogram(aes(p.value.fdr, fill = DATASET), bins = 100) +
  scale_x_continuous(breaks = 0:5/5)


masst_results %>% 
  filter(p.value.fdr < 0.1) %>% 
  ggplot() +
  geom_histogram(aes(p.value.fdr, fill = DATASET), bins = 100) +
  scale_x_continuous(breaks = 0:5/50)


masst_results %>% 
    filter(p.value.fdr < 0.01) %>% 
  ggplot() +
  geom_histogram(aes(p.value.fdr, fill = DATASET), bins = 100) +
  scale_x_continuous(breaks = 0:5/500)


masst_results %>% 
  filter(p.value.fdr < 0.001) %>% 
  ggplot() +
  geom_histogram(aes(p.value.fdr, fill = DATASET), bins = 100) +
  scale_x_continuous(breaks = 0:5/5000)

Filter for a p-value < 0.01:

masst_results <- masst_results %>% 
  filter(p.value.fdr < 0.01)

masst_results

Number of significant hits per dataset:

masst_results %>% 
  count(DATASET)

Number of significant hits per dataset:

masst_results %>% 
  group_by(DATASET) %>% 
  summarize(N_FEATURES = n_distinct(FEATURE_ID))

Export significant hits for Cytoscape:

masst_results %>% 
  mutate(`shared name` = FEATURE_ID %>% str_sub(-5, -1) %>% as.integer()) %>% 
  group_by(DATASET, `shared name`) %>% 
  summarize(MASST_PHYLA = NAME %>% sort() %>% str_c(collapse = ", "), .groups = "drop_last") %>% 
  nest() %>% 
  mutate(
    FILE_NAME = DATASET %>% str_remove("_") %>% str_c(".tsv"),
    DUMMY = map2(data, FILE_NAME, ~ write_tsv(.x, .y))
  )

Map MASST results from features to families

Read feature annotations from file:

feature_info <- rbind(
  read_tsv("feature_metadata/C18neg_feature_metadata_consolidated_is_microbial.tsv", guess_max = 100000) %>% 
    mutate(MET_CHEM_NO = paste0("X95", formatC(`#featureID`,        width = 5, flag = "0", format = "d"))) %>% 
    mutate(FAMILY_ID   = paste0("X95", formatC(GNPS_componentindex, width = 4, flag = "0", format = "d"))),
  read_tsv("feature_metadata/C18pos_feature_metadata_consolidated_is_microbial.tsv", guess_max = 100000) %>% 
    mutate(MET_CHEM_NO = paste0("X94", formatC(`#featureID`,        width = 5, flag = "0", format = "d"))) %>% 
    mutate(FAMILY_ID   = paste0("X94", formatC(GNPS_componentindex, width = 4, flag = "0", format = "d"))),
  read_tsv("feature_metadata/HILICneg_feature_metadata_consolidated_is_microbial.tsv", guess_max = 100000) %>% 
    mutate(MET_CHEM_NO = paste0("X97", formatC(`#featureID`,        width = 5, flag = "0", format = "d"))) %>% 
    mutate(FAMILY_ID   = paste0("X97", formatC(GNPS_componentindex, width = 4, flag = "0", format = "d"))),
  read_tsv("feature_metadata/HILICpos_feature_metadata_consolidated_is_microbial.tsv", guess_max = 100000) %>% 
    mutate(MET_CHEM_NO = paste0("X96", formatC(`#featureID`,        width = 5, flag = "0", format = "d"))) %>% 
    mutate(FAMILY_ID   = paste0("X96", formatC(GNPS_componentindex, width = 4, flag = "0", format = "d")))
  ) %>% 
  mutate(FAMILY_ID = if_else(str_detect(FAMILY_ID, "-001$"), "Singleton", FAMILY_ID))
Rows: 6155 Columns: 256
-- Column specification ----------------------------------------------------------------------------------------------------------------------------------
Delimiter: "\t"
chr (159): GNPS_Best Ion, GNPS_GNPSLinkout_Cluster, GNPS_GNPSLinkout_Network, GNPS_INCHI, GNPS_LibraryID, GNPS_MS2 Verification Comment, GNPS_Smiles, ...
dbl  (91): #featureID, GNPS_Annotated Adduct Features ID, GNPS_Correlated Features Group ID, GNPS_G1, GNPS_G2, GNPS_G3, GNPS_G4, GNPS_G5, GNPS_G6, GNP...
lgl   (6): GNPS_LIB_Pubmed_ID, GNPS_LIB_INCHI_AUX, GNPS_LIB_tags, GNPS_LIBA_INCHI_AUX, GNPS_LIBA_tags, CSI_ConfidenceScore

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
Rows: 15131 Columns: 256
-- Column specification ----------------------------------------------------------------------------------------------------------------------------------
Delimiter: "\t"
chr (158): GNPS_GNPSLinkout_Cluster, GNPS_GNPSLinkout_Network, GNPS_INCHI, GNPS_LibraryID, GNPS_Smiles, GNPS_SpectrumID, GNPS_LIB_SpectrumID, GNPS_LIB...
dbl  (90): #featureID, GNPS_G1, GNPS_G2, GNPS_G3, GNPS_G4, GNPS_G5, GNPS_G6, GNPS_MQScore, GNPS_RTConsensus, GNPS_RTMean, GNPS_RTStdErr, GNPS_SumPeakI...
lgl   (8): GNPS_Annotated Adduct Features ID, GNPS_Best Ion, GNPS_Correlated Features Group ID, GNPS_MS2 Verification Comment, GNPS_neutral M mass, GN...

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
Rows: 11230 Columns: 256
-- Column specification ----------------------------------------------------------------------------------------------------------------------------------
Delimiter: "\t"
chr (153): GNPS_GNPSLinkout_Cluster, GNPS_GNPSLinkout_Network, GNPS_INCHI, GNPS_LibraryID, GNPS_Smiles, GNPS_SpectrumID, GNPS_LIB_SpectrumID, GNPS_LIB...
dbl  (89): #featureID, GNPS_Correlated Features Group ID, GNPS_G1, GNPS_G2, GNPS_G3, GNPS_G4, GNPS_G5, GNPS_G6, GNPS_MQScore, GNPS_RTConsensus, GNPS_R...
lgl  (14): GNPS_Annotated Adduct Features ID, GNPS_Best Ion, GNPS_MS2 Verification Comment, GNPS_neutral M mass, GNPS_LIB_INCHI_AUX, GNPS_LIB_tags, GN...

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
Rows: 28762 Columns: 256
-- Column specification ----------------------------------------------------------------------------------------------------------------------------------
Delimiter: "\t"
chr (161): GNPS_Best Ion, GNPS_GNPSLinkout_Cluster, GNPS_GNPSLinkout_Network, GNPS_INCHI, GNPS_LibraryID, GNPS_MS2 Verification Comment, GNPS_Smiles, ...
dbl  (92): #featureID, GNPS_Annotated Adduct Features ID, GNPS_Correlated Features Group ID, GNPS_G1, GNPS_G2, GNPS_G3, GNPS_G4, GNPS_G5, GNPS_G6, GNP...
lgl   (3): GNPS_LIB_INCHI_AUX, GNPS_LIBA_INCHI_AUX, CSI_ConfidenceScore

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Add FAMILY_ID to the MASST results:

masst_results <- masst_results %>% 
  inner_join(
    feature_info %>% 
      select(FEATURE_ID = MET_CHEM_NO, FAMILY_ID)
  )
Joining, by = "FEATURE_ID"
masst_results

Number of significant hits per dataset:

masst_results %>% 
  group_by(DATASET) %>% 
  summarize(N_FAMILIES = n_distinct(FAMILY_ID), n = n())

Statistical analysis of features

Read statistical results from file:

skin_p_cat_dir <- read_tsv("Untargeted.p_cat_dir.tsv")
Rows: 33333 Columns: 15
-- Column specification ----------------------------------------------------------------------------------------------------------------------------------
Delimiter: "\t"
chr (15): MET_CHEM_NO, p_cat_dir|base|sebum, p_cat_dir|base|skicon, p_cat_dir|groups|oily-norm, p_cat_dir|groups|skicon, p_cat_dir|oily|exfol, p_cat_d...

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
skin_p_value   <- read_tsv("Untargeted.p_value.tsv")
Rows: 44567 Columns: 15
-- Column specification ----------------------------------------------------------------------------------------------------------------------------------
Delimiter: "\t"
chr  (1): MET_CHEM_NO
dbl (14): p_value|base|sebum, p_value|base|skicon, p_value|groups|oily-norm, p_value|groups|skicon, p_value|oily|exfol, p_value|oily|F-B, p_value|oily...

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
skin_p_cat_dir %>% colnames()
 [1] "MET_CHEM_NO"                "p_cat_dir|base|sebum"       "p_cat_dir|base|skicon"      "p_cat_dir|groups|oily-norm" "p_cat_dir|groups|skicon"   
 [6] "p_cat_dir|oily|exfol"       "p_cat_dir|oily|F-B"         "p_cat_dir|oily|F-B|A"       "p_cat_dir|oily|F-B|B"       "p_cat_dir|oily|F-B|B-A"    
[11] "p_cat_dir|oily|F-B|C"       "p_cat_dir|oily|F-B|C-A"     "p_cat_dir|oily|F-B|C-B"     "p_cat_dir|oily|sebum"       "p_cat_dir|oily|skicon"     
skin_stats <- skin_p_value %>% 
  select(MET_CHEM_NO) %>% 
  left_join(skin_p_cat_dir, by = "MET_CHEM_NO") %>% 
  mutate(
    sebumeter_0.1_any  = `p_cat_dir|base|sebum` %>% is.na(.) %>% not(),
    sebumeter_0.1_up   = `p_cat_dir|base|sebum` %>% is.na(.) %>% not() & `p_cat_dir|base|sebum` %>% str_detect("Up"),
    sebumeter_0.1_down = `p_cat_dir|base|sebum` %>% is.na(.) %>% not() & `p_cat_dir|base|sebum` %>% str_detect("Dn")
  )

skin_stats %>% 
  group_by(`p_cat_dir|base|sebum`, sebumeter_0.1_any) %>% summarize(.groups = "drop")

skin_stats %>% 
  group_by(`p_cat_dir|base|sebum`, sebumeter_0.1_up) %>% summarize(.groups = "drop")

skin_stats %>% 
  group_by(`p_cat_dir|base|sebum`, sebumeter_0.1_down) %>% summarize(.groups = "drop")

Check whether there are skin stats for all features from the MASST results:

masst_results_stats <- masst_results %>% 
  inner_join(
    skin_stats %>% 
      select(FEATURE_ID = MET_CHEM_NO, sebumeter_0.1_any, sebumeter_0.1_up, sebumeter_0.1_down),
    by = "FEATURE_ID"
  )

setdiff(masst_results$FEATURE_ID, skin_stats$MET_CHEM_NO)
character(0)

Features correlated with sebumeter score

Which features that are positively correlated with sebumeter score are associated with microbes? The figures in each table call are the fdr-corrected p-values for the associations between features and phyla:

masst_results_stats %>% 
  filter(sebumeter_0.1_up) %>% 
  pivot_wider(c(FEATURE_ID, DATASET), names_from = NAME, values_from = p.value.fdr)

Which features that are negatively correlated with sebumeter score are associated with microbes? The figures in each table call are the fdr-corrected p-values for the associations between features and phyla:

masst_results_stats %>% 
  filter(sebumeter_0.1_down) %>% 
  pivot_wider(c(FEATURE_ID, DATASET), names_from = NAME, values_from = p.value.fdr)

Enrichment analysis of features

  • Are the features associated with a particular phylum enriched in positive or negative correlations with sebumeter score?
    • Null hypothesis: All features associated with a particular phylum are uncorrelated with sebumeter score.
    • Can be tested by taking the alpha error rate that was used when testing for correlation and assuming a binomial distribution across all features associated with that phylum.
    • Needs the total number of features, but not the total number of phyla.

Calculation of binomial distribution:

  • N_FEATURES: Number of features significantly associated with the respective phylum, regardless of their correlation with sebumeter score
  • N_ANY: Number of features significantly associated with the respective phylum and significantly correlated with sebumeter score, regardless of direction
  • N_POS: Number of features significantly associated with the respective phylum and positively correlated with sebumeter score
  • N_NEG: Number of features significantly associated with the respective phylum and negatively correlated with sebumeter score

The binomial distribution gives the probability that the observed or a higher number of features is correlated with sebumeter score just by chance (false positives).

p_alpha <- 0.1

masst_results_stats %>% 
  group_by(NAME) %>% 
  summarize(
    N_FEATURES = n(),
    N_ANY      = sum(sebumeter_0.1_any),
    N_POS      = sum(sebumeter_0.1_up),
    N_NEG      = sum(sebumeter_0.1_down)
  ) %>% 
  rowwise() %>% 
  mutate(
    PBINOM_ANY = pbinom(N_ANY, N_FEATURES, p_alpha, lower.tail = F) %>% format(digits = 2),
    PBINOM_POS = pbinom(N_POS, N_FEATURES, p_alpha, lower.tail = F) %>% format(digits = 2),
    PBINOM_NEG = pbinom(N_NEG, N_FEATURES, p_alpha, lower.tail = F) %>% format(digits = 2)
  )
  • A significant enrichment is found only for phyla with few associated features:
    • Bacillariophyta show a significant enrichment of associated features which are negatively correlated with sebumeter score
    • Euglenozoa show a significant enrichment of associated features which are negatively correlated with sebumeter score

Are these enrichments false positives, or are significant correlations with sebumeter score diluted by statistical noise in the phyla with many associated features?

Statistical analysis of families

Read statistical results from file:

skin_p_cat_dir <- read_tsv("Aggregated_p_cat_dir.tsv")
Rows: 971 Columns: 16
-- Column specification ----------------------------------------------------------------------------------------------------------------------------------
Delimiter: "\t"
chr (15): FAMILY_ID, p_cat_dir|base|sebum, p_cat_dir|base|skicon, p_cat_dir|groups|oily-norm, p_cat_dir|groups|skicon, p_cat_dir|oily|exfol, p_cat_dir...
dbl  (1): row_id

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
skin_p_value   <- read_tsv("Aggregated_p_value.tsv")
Rows: 1225 Columns: 16
-- Column specification ----------------------------------------------------------------------------------------------------------------------------------
Delimiter: "\t"
chr  (1): FAMILY_ID
dbl (15): row_id, p_value|base|sebum, p_value|base|skicon, p_value|groups|oily-norm, p_value|groups|skicon, p_value|oily|exfol, p_value|oily|F-B, p_va...

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
skin_p_cat_dir %>% colnames()
 [1] "FAMILY_ID"                  "row_id"                     "p_cat_dir|base|sebum"       "p_cat_dir|base|skicon"      "p_cat_dir|groups|oily-norm"
 [6] "p_cat_dir|groups|skicon"    "p_cat_dir|oily|exfol"       "p_cat_dir|oily|F-B"         "p_cat_dir|oily|F-B|A"       "p_cat_dir|oily|F-B|B"      
[11] "p_cat_dir|oily|F-B|B-A"     "p_cat_dir|oily|F-B|C"       "p_cat_dir|oily|F-B|C-A"     "p_cat_dir|oily|F-B|C-B"     "p_cat_dir|oily|sebum"      
[16] "p_cat_dir|oily|skicon"     
skin_stats <- skin_p_value %>% 
  select(FAMILY_ID) %>% 
  left_join(skin_p_cat_dir, by = "FAMILY_ID") %>% 
  mutate(
    sebumeter_0.1_any  = `p_cat_dir|base|sebum` %>% is.na(.) %>% not(),
    sebumeter_0.1_up   = `p_cat_dir|base|sebum` %>% is.na(.) %>% not() & `p_cat_dir|base|sebum` %>% str_detect("Up"),
    sebumeter_0.1_down = `p_cat_dir|base|sebum` %>% is.na(.) %>% not() & `p_cat_dir|base|sebum` %>% str_detect("Dn")
  )

skin_stats %>% 
  group_by(`p_cat_dir|base|sebum`, sebumeter_0.1_any) %>% summarize(.groups = "drop")

skin_stats %>% 
  group_by(`p_cat_dir|base|sebum`, sebumeter_0.1_up) %>% summarize(.groups = "drop")

skin_stats %>% 
  group_by(`p_cat_dir|base|sebum`, sebumeter_0.1_down) %>% summarize(.groups = "drop")

Aggregate by phylum and family:

masst_results_family <- masst_results %>% 
  group_by(NAME, FAMILY_ID) %>% 
  summarize(N_FEATURES = n(), .groups = "drop")

masst_results_family

Check whether there are skin stats for all families from the MASST results:

masst_results_stats <- masst_results_family %>% 
  inner_join(
    skin_stats %>% 
      select(FAMILY_ID, sebumeter_0.1_any, sebumeter_0.1_up, sebumeter_0.1_down),
    by = "FAMILY_ID"
  )

setdiff(masst_results$FAMILY_ID, skin_stats$FAMILY_ID)
[1] "X970885" "X961864" "X950468" "X940057"

Why are these families missing?

feature_info %>% 
  filter(FAMILY_ID %in% c("X970885", "X961864", "X950468", "X940057")) %>% 
  count(FAMILY_ID)

Families correlated with sebumeter score

Which families that are positively correlated with sebumeter score are associated with microbes? The figures in each table call are the number of features from that family which are associated with the respective phylum:

masst_results_stats %>% 
  filter(sebumeter_0.1_up) %>% 
  inner_join(
    feature_info %>% 
      count(FAMILY_ID),
    by = "FAMILY_ID"
  ) %>% 
  pivot_wider(c(FAMILY_ID, n), names_from = NAME, values_from = N_FEATURES, names_sort = T) %>% 
  arrange(FAMILY_ID)
  • X940029 is a big family comprising 99 features, of which several are associated with different phyla. This family is interesting.
  • X950190 is a medium-size family comprising 22 features, of which only one is associated with Basidiomycota.

Which families that are positively correlated with sebumeter score are associated with microbes? The figures in each table call are the number of features from that family which are associated with the respective phylum:

masst_results_stats %>% 
  filter(sebumeter_0.1_down) %>% 
  inner_join(
    feature_info %>% 
      count(FAMILY_ID),
    by = "FAMILY_ID"
  ) %>% 
  pivot_wider(c(FAMILY_ID, n), names_from = NAME, values_from = N_FEATURES, names_sort = T) %>% 
  arrange(FAMILY_ID)
  • X940005 is a big family comprising 86 features, of which several are associated with different phyla. This family is interesting.
  • X950477 is a medium-size family comprising 17 features, of which one is associated with Actinobacteria and one with Basidiomycota (could be the same feature).
  • X970034 is a medium-size family comprising 17 features, of which one is associated with Ascomycota and one with Bacillariophyta (could be the same feature).
  • X950167 is a medium-size family comprising 16 features, of which 6 are associated with Euglenozoa. This may be interesting, but the role of euglenozoa on the skin is unclear to me. However see https://royalsocietypublishing.org/doi/10.1098/rsob.200407

Enrichment analysis of families

  • Are the features associated with a particular phylum enriched in positive or negative correlations with sebumeter score?
    • Null hypothesis: All features associated with a particular phylum are uncorrelated with sebumeter score.
    • Can be tested by taking the alpha error rate that was used when testing for correlation and assuming a binomial distribution across all features associated with that phylum.
    • Needs the total number of features, but not the total number of phyla.

Calculation of binomial distribution:

  • N_FEATURES: Number of features significantly associated with the respective phylum, regardless of their correlation with sebumeter score
  • N_FAMILIES: Number of families significantly associated with the respective phylum, regardless of their correlation with sebumeter score
  • N_ANY: Number of families significantly associated with the respective phylum and significantly correlated with sebumeter score, regardless of direction
  • N_POS: Number of families significantly associated with the respective phylum and positively correlated with sebumeter score
  • N_NEG: Number of families significantly associated with the respective phylum and negatively correlated with sebumeter score

The binomial distribution gives the probability that the observed or a higher number of families is correlated with sebumeter score just by chance (false positives).

p_alpha <- 0.1

masst_results_stats %>% 
  group_by(NAME) %>% 
  summarize(
    N_FEATURES = sum(N_FEATURES),
    N_FAMILIES = n(),
    N_ANY      = sum(sebumeter_0.1_any),
    N_POS      = sum(sebumeter_0.1_up),
    N_NEG      = sum(sebumeter_0.1_down)
  ) %>% 
  rowwise() %>% 
  mutate(
    PBINOM_CHANGED = pbinom(N_ANY, N_FAMILIES, p_alpha, lower.tail = F) %>% format(digits = 2),
    PBINOM_UP      = pbinom(N_POS, N_FAMILIES, p_alpha, lower.tail = F) %>% format(digits = 2),
    PBINOM_DOWN    = pbinom(N_NEG, N_FAMILIES, p_alpha, lower.tail = F) %>% format(digits = 2)
  )
  • A significant enrichment is found only for phyla with few associated families:
    • Spirochaetes show a significant enrichment of associated features which are positively or negatively correlated with sebumeter score
    • Zoopagomycota show a significant enrichment of associated features which are positively correlated with sebumeter score

These are different phyla than found in the enrichment analysis on features, which is another indication that the enrichment may not be meaningful. Individual associations may of course still be meaningful.

Interesting molecular families

Families positively correlated with sebumeter score

X940029

X940029

masst_results %>% 
  filter(FAMILY_ID == "X940029") %>% 
  pivot_wider(FEATURE_ID, names_from = NAME, values_from = p.value.fdr, names_sort = T) %>% 
  arrange(FEATURE_ID)

X9400174

masst_results %>% 
  filter(FEATURE_ID == "X9400174") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9400174"

$PHYLA
[1] "Ascomycota, Cyanobacteria, Firmicutes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9400174") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9400174"

$Cons_SMILES
[1] "CCCCCCC=CCCCCCCCC(=O)OCC"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "283.2625 C18H34O2 Palmitoleic acid ethyl ester"

$Cons_Name_ClassyFire
[1] "283.2625 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Organic acids and derivatives; Carboxylic acids and derivatives; Organooxygen compounds; Fatty acid esters; Carboxylic acid derivatives; Monocarboxylic acids and derivatives; Carboxylic acid esters; Carbonyl compounds; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9400257

masst_results %>% 
  filter(FEATURE_ID == "X9400257") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9400257"

$PHYLA
[1] "Arthropoda, Cyanobacteria, Firmicutes, Spirochaetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9400257") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9400257"

$Cons_SMILES
[1] "CCCCCCC=CCCCCCCCC(=O)OCC(O)CO"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "329.2673 C19H36O4 Monopalmitolein (9c)"

$Cons_Name_ClassyFire
[1] "329.2673 Glycerolipids M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Glycerolipids; Organic acids and derivatives; Carboxylic acids and derivatives; Primary alcohols; Organooxygen compounds; Fatty acid esters; Carboxylic acid derivatives; Monoacylglycerols; Monocarboxylic acids and derivatives; Carboxylic acid esters; 1-monoacylglycerols; Secondary alcohols; Carbonyl compounds; Polyols; Monoradylglycerols; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9400316

masst_results %>% 
  filter(FEATURE_ID == "X9400316") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9400316"

$PHYLA
[1] "Chordata, Zoopagomycota, Basidiomycota, Ascomycota, Actinobacteria, Firmicutes, Spirochaetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9400316") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9400316"

$Cons_SMILES
[1] "CCCCCCCCC=CCCCCCCCC(=O)OCC(O)CO"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "357.2983 C21H40O4 Monoelaidin"

$Cons_Name_ClassyFire
[1] "357.2983 Glycerolipids M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Glycerolipids; Organic acids and derivatives; Carboxylic acids and derivatives; Primary alcohols; Organooxygen compounds; Fatty acid esters; Carboxylic acid derivatives; Monocarboxylic acids and derivatives; Carboxylic acid esters; Secondary alcohols; Carbonyl compounds; Polyols; Monoradylglycerols; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9400904

masst_results %>% 
  filter(FEATURE_ID == "X9400904") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9400904"

$PHYLA
[1] "Ascomycota, Cyanobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9400904") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9400904"

$Cons_SMILES
[1] "CCCCCCCCC=CCCCCCCCC(=O)OCC"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "328.3194 C20H38O2 Oleic acid ethyl ester"

$Cons_Name_ClassyFire
[1] "328.3194 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Fatty acids and conjugates; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Organooxygen compounds; Amino fatty acids; Carboxylic acid derivatives; Monocarboxylic acids and derivatives; Carboxylic acids; Carbonyl compounds; Long-chain fatty acids; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9401121

masst_results %>% 
  filter(FEATURE_ID == "X9401121") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9401121"

$PHYLA
[1] "Basidiomycota"
feature_info %>% 
  filter(MET_CHEM_NO == "X9401121") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9401121"

$Cons_SMILES
[1] "CCCCCCCCC=CCCCCCCCC(=O)OCC(O)CO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "374.3242 C21H40O4 Monoolein"

$Cons_Name_ClassyFire
[1] "374.3242 Glycerolipids M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Glycerolipids; Organic acids and derivatives; Carboxylic acids and derivatives; Primary alcohols; Organooxygen compounds; Fatty acid esters; Carboxylic acid derivatives; Monoacylglycerols; Monocarboxylic acids and derivatives; Carboxylic acid esters; Secondary alcohols; Carbonyl compounds; Polyols; Monoradylglycerols; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9401123

masst_results %>% 
  filter(FEATURE_ID == "X9401123") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9401123"

$PHYLA
[1] "Actinobacteria, Cyanobacteria, Spirochaetes"
feature_info %>% 
  filter(MET_CHEM_NO == "X9401123") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9401123"

$Cons_SMILES
[1] "CCCCCC/C=C\\CCCCCCCC(=O)OCC"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "255.2306 C16H30O2 Palmitoleic Acid ethyl ester"

$Cons_Name_ClassyFire
[1] "255.2306 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Primary alcohols; Organooxygen compounds; Fatty alcohols; Fatty Acyls; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9402192

masst_results %>% 
  filter(FEATURE_ID == "X9402192") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9402192"

$PHYLA
[1] "Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9402192") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9402192"

$Cons_SMILES
[1] "CCCCCC=CCC=CCCCCCCCC(=O)OC"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "326.3035 C20H36O2 Linoleic acid methyl ester"

$Cons_Name_ClassyFire
[1] "326.3035 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Organooxygen compounds; Fatty amides; Carboxylic acid amides; Carboxylic acid derivatives; N-acyl amines; Secondary carboxylic acid amides; Carbonyl compounds; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9402417

masst_results %>% 
  filter(FEATURE_ID == "X9402417") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9402417"

$PHYLA
[1] "Arthropoda"
feature_info %>% 
  filter(MET_CHEM_NO == "X9402417") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9402417"

$Cons_SMILES
[1] "CCCCCCCCC=CCCCCCCCC(=O)OCC(O)CO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "315.2515 C17H32N4 Monoolein"

$Cons_Name_ClassyFire
[1] "315.2515 Glycerolipids M+H"

$`CAN_all classifications`
[1] "Organic compounds; Organoheterocyclic compounds; Organonitrogen compounds; Azoles; Amines; Azacyclic compounds; Heteroaromatic compounds; Hydrocarbon derivatives; Organopnictogen compounds; Organic nitrogen compounds; Chemical entities"

X9402498

masst_results %>% 
  filter(FEATURE_ID == "X9402498") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9402498"

$PHYLA
[1] "Actinobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9402498") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9402498"

$Cons_SMILES
[1] "CCCCCC=CCC=CCCCCCCCC(=O)OC(CO)CO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "373.2926 C21H40O5 2-Linoleoylglycerol"

$Cons_Name_ClassyFire
[1] "373.2926 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Glycerolipids; Organic acids and derivatives; Carboxylic acids and derivatives; Primary alcohols; Organooxygen compounds; Fatty acid esters; Carboxylic acid derivatives; Monocarboxylic acids and derivatives; Carboxylic acid esters; Secondary alcohols; Carbonyl compounds; Polyols; Monoradylglycerols; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9402674

masst_results %>% 
  filter(FEATURE_ID == "X9402674") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9402674"

$PHYLA
[1] "Cyanobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9402674") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9402674"

$Cons_SMILES
[1] "CCCCCCCCC=CCCCCCC(=O)OC"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "300.2883 C18H34O2 cis-7-Hexadecenoic acid methyl ester"

$Cons_Name_ClassyFire
[1] "300.2883 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Organooxygen compounds; Carbonyl compounds; Amines; Alkanolamines; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9404362

masst_results %>% 
  filter(FEATURE_ID == "X9404362") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9404362"

$PHYLA
[1] "Basidiomycota, Ascomycota, Cyanobacteria, Firmicutes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9404362") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9404362"

$Cons_SMILES
[1] "CCCCCCC=CCCCCCCCC(=O)OCC"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "283.2614 C18H34O2 Palmitoleic acid ethyl ester"

$Cons_Name_ClassyFire
[1] "283.2614 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Organic acids and derivatives; Carboxylic acids and derivatives; Organooxygen compounds; Fatty acid esters; Carboxylic acid derivatives; Monocarboxylic acids and derivatives; Carboxylic acid esters; Carbonyl compounds; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9404581

masst_results %>% 
  filter(FEATURE_ID == "X9404581") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9404581"

$PHYLA
[1] "Ascomycota, Actinobacteria, Firmicutes, Bacteroidetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9404581") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9404581"

$Cons_SMILES
[1] "CCCCCCCCC=CCCCCCCCCCCCC(=O)OCC(O)CO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "384.381 C24H46O2 Monoerucin"

$Cons_Name_ClassyFire
[1] "384.381 Glycerolipids M+H-H2O"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Fatty acids and conjugates; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Fatty amides; Carboxylic acid amides; Carboxylic acid derivatives; N-acyl amines; Monocarboxylic acids and derivatives; Carboxylic acids; Secondary alcohols; Secondary carboxylic acid amides; Carbonyl compounds; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9407909

masst_results %>% 
  filter(FEATURE_ID == "X9407909") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9407909"

$PHYLA
[1] "Actinobacteria, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9407909") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9407909"

$Cons_SMILES
[1] "CCCCCCCCC=CCCCCCCCC(=O)OCC(O)CO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "343.2834 C20H38O4 Monoelaidin"

$Cons_Name_ClassyFire
[1] "343.2834 Glycerolipids M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Glycerolipids; Organic acids and derivatives; Carboxylic acids and derivatives; Primary alcohols; Organooxygen compounds; Fatty acid esters; Carboxylic acid derivatives; Monoacylglycerols; Monocarboxylic acids and derivatives; Carboxylic acid esters; 1-monoacylglycerols; Secondary alcohols; Carbonyl compounds; Polyols; Monoradylglycerols; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9409048

masst_results %>% 
  filter(FEATURE_ID == "X9409048") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9409048"

$PHYLA
[1] "Ascomycota, Actinobacteria, Firmicutes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9409048") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9409048"

$Cons_SMILES
[1] "CCCCCCCCC=CCCCCCC(=O)OC"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "269.2461 C17H32O2 cis-7-Hexadecenoic acid methyl ester"

$Cons_Name_ClassyFire
[1] "269.2461 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Organic acids and derivatives; Carboxylic acids and derivatives; Organooxygen compounds; Fatty acid esters; Carboxylic acid derivatives; Monocarboxylic acids and derivatives; Carboxylic acid esters; Fatty alcohols; Secondary alcohols; Carbonyl compounds; Methyl esters; Fatty acid methyl esters; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9421045

masst_results %>% 
  filter(FEATURE_ID == "X9421045") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9421045"

$PHYLA
[1] "Zoopagomycota"
feature_info %>% 
  filter(MET_CHEM_NO == "X9421045") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9421045"

$Cons_SMILES
[1] "CCCCCC=CCC=CCCCCCCCC(=O)OC(COC(=O)CCCCCCCCCCCCCCC)COP(=O)([O-])OCC[NH3+]"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "575.5076 2-Linoleoyl-1-palmitoyl-sn-glycero-3-phosphoethanolamine"

$Cons_Name_ClassyFire
[1] "575.5076 Glycerophospholipids M+H-C2H8NO4P"

$`CAN_all classifications`
[1] NA

X9421657

masst_results %>% 
  filter(FEATURE_ID == "X9421657") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9421657"

$PHYLA
[1] "Bacteroidetes"
feature_info %>% 
  filter(MET_CHEM_NO == "X9421657") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9421657"

$Cons_SMILES
[1] "CCCCCCC=CCCCCCCCC(=O)NC1CCOC1=O"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "312.288 C19H39NO3 N-cis-Hexadec-9-enoyl-L-homoserine lactone"

$Cons_Name_ClassyFire
[1] "312.288 Carboxylic acids and derivatives M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Fatty amides; Carboxylic acid amides; Carboxylic acid derivatives; N-acyl amines; Secondary alcohols; Secondary carboxylic acid amides; Carbonyl compounds; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9423263

masst_results %>% 
  filter(FEATURE_ID == "X9423263") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9423263"

$PHYLA
[1] "Chordata"
feature_info %>% 
  filter(MET_CHEM_NO == "X9423263") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9423263"

$Cons_SMILES
[1] "CCCCC=CCCCCCCCC(=O)OC"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "241.215 C15H28O2 Methyl myristoleate"

$Cons_Name_ClassyFire
[1] "241.215 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Organic acids and derivatives; Carboxylic acids and derivatives; Organooxygen compounds; Fatty acid esters; Carboxylic acid derivatives; Monocarboxylic acids and derivatives; Carboxylic acid esters; Carbonyl compounds; Methyl esters; Fatty acid methyl esters; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9423629

masst_results %>% 
  filter(FEATURE_ID == "X9423629") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9423629"

$PHYLA
[1] "Chordata"
feature_info %>% 
  filter(MET_CHEM_NO == "X9423629") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9423629"

$Cons_SMILES
[1] "CCCCC=CCCCCCCCC(=O)OC"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "241.2149 C15H28O2 Methyl myristoleate"

$Cons_Name_ClassyFire
[1] "241.2149 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Organic acids and derivatives; Carboxylic acids and derivatives; Organooxygen compounds; Fatty acid esters; Carboxylic acid derivatives; Monocarboxylic acids and derivatives; Carboxylic acid esters; Carbonyl compounds; Methyl esters; Fatty acid methyl esters; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9426846

masst_results %>% 
  filter(FEATURE_ID == "X9426846") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9426846"

$PHYLA
[1] "Ascomycota"
feature_info %>% 
  filter(MET_CHEM_NO == "X9426846") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9426846"

$Cons_SMILES
[1] "CCCCC=CCCCCCCCC(=O)OC"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "272.257 C16H30O2 Methyl myristoleate"

$Cons_Name_ClassyFire
[1] "272.257 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Monoalkylamines; Carbonyl compounds; Amines; Primary amines; Alkanolamines; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9430538

masst_results %>% 
  filter(FEATURE_ID == "X9430538") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9430538"

$PHYLA
[1] "Basidiomycota, Ascomycota"
feature_info %>% 
  filter(MET_CHEM_NO == "X9430538") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9430538"

$Cons_SMILES
[1] "CCCCCC=CCC=CCCCCCCCC(=O)OCC(O)CO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "372.3445 C22H42O3 1-Linoleoylglycerol"

$Cons_Name_ClassyFire
[1] "372.3445 Fatty Acyls M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Glycerolipids; Organic acids and derivatives; Carboxylic acids and derivatives; Primary alcohols; Organooxygen compounds; Fatty acid esters; Lineolic acids and derivatives; Carboxylic acid derivatives; Monoacylglycerols; Monocarboxylic acids and derivatives; Carboxylic acid esters; 1-monoacylglycerols; Carbonyl compounds; Polyols; 1,2-diols; Monoradylglycerols; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9433405

masst_results %>% 
  filter(FEATURE_ID == "X9433405") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9433405"

$PHYLA
[1] "Chordata, Ascomycota, Actinobacteria, Firmicutes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9433405") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9433405"

$Cons_SMILES
[1] "CCCCCCCCC=CCCCCCCCC(=O)OCC(O)CO"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "339.2871 C19H40O3 Monoelaidin"

$Cons_Name_ClassyFire
[1] "339.2871 Glycerolipids M+H-H2O"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Glycerolipids; Ethers; Primary alcohols; Organooxygen compounds; Dialkyl ethers; Secondary alcohols; Polyols; Glycerol ethers; 1,2-diols; Monoalkylglycerols; Monoradylglycerols; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X950190

X950190

masst_results %>% 
  filter(FAMILY_ID == "X950190") %>% 
  pivot_wider(FEATURE_ID, names_from = NAME, values_from = p.value.fdr, names_sort = T) %>% 
  arrange(FEATURE_ID)

X9502693

masst_results %>% 
  filter(FEATURE_ID == "X9502693") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9502693"

$PHYLA
[1] "Basidiomycota"
feature_info %>% 
  filter(MET_CHEM_NO == "X9502693") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9502693"

$Cons_SMILES
[1] "CCCCCC(CC(=O)CCCCCC(CC(=O)CCCCCCC(=O)CC(CCCCCC(=O)CC(CCCCC)O)O)O)O"

$Cons_Highest_annot
[1] "SIRIUS_CSI"

$Cons_Name
[1] "617.4741 C38H70O8"

$Cons_Name_ClassyFire
[1] "617.4741 Very long-chain fatty acids [M - H4O2 - H]-"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Fatty acids and conjugates; Organic acids and derivatives; Carboxylic acids and derivatives; Organooxygen compounds; Branched fatty acids; Unsaturated fatty acids; Hydroxy fatty acids; Dicarboxylic acids and derivatives; Carboxylic acids; Secondary alcohols; Carbonyl compounds; Long-chain fatty acids; Very long-chain fatty acids; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

Families negatively correlated with sebumeter score

X940005

X940005

masst_results %>% 
  filter(FAMILY_ID == "X940005") %>% 
  pivot_wider(FEATURE_ID, names_from = NAME, values_from = p.value.fdr, names_sort = T) %>% 
  arrange(FEATURE_ID)

X9401814

masst_results %>% 
  filter(FEATURE_ID == "X9401814") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9401814"

$PHYLA
[1] "Chordata, Basidiomycota, Ascomycota, Actinobacteria, Cyanobacteria, Firmicutes, Bacteroidetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9401814") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9401814"

$Cons_SMILES
[1] "C1CCC2OCCOCCOCCOC3CCCCC3OCCOCCOCCOC2C1"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "424.3609 C18H49N7O6 Dicyclohexano-24-crown-8"

$Cons_Name_ClassyFire
[1] "424.3609 Organooxygen compounds M+NH4"

$`CAN_all classifications`
[1] "Organic compounds; Alcohols and polyols; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Monoalkylamines; Amines; Primary amines; Alkanolamines; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9402252

masst_results %>% 
  filter(FEATURE_ID == "X9402252") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9402252"

$PHYLA
[1] "Chordata, Ascomycota, Cyanobacteria, Firmicutes, Spirochaetes, Bacteroidetes"
feature_info %>% 
  filter(MET_CHEM_NO == "X9402252") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9402252"

$Cons_SMILES
[1] "CCNC1CC(C(C(C1OC2C(C(C(CO2)(C)O)NC)O)O)OC3C(CC=C(O3)CN)N)N"

$Cons_Highest_annot
[1] "SIRIUS_CSI"

$Cons_Name
[1] "476.3034 C21H41N5O7 Netililn"

$Cons_Name_ClassyFire
[1] "476.3034 Alkanolamines [M + H]+"

$`CAN_all classifications`
[1] "Organic compounds; Alcohols and polyols; Ethers; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Monoalkylamines; Dialkyl ethers; Amines; Primary amines; Alkanolamines; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9402352

masst_results %>% 
  filter(FEATURE_ID == "X9402352") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9402352"

$PHYLA
[1] "Chordata, Ascomycota, Cyanobacteria, Firmicutes, Spirochaetes, Bacteroidetes"
feature_info %>% 
  filter(MET_CHEM_NO == "X9402352") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9402352"

$Cons_SMILES
[1] "CC(C)n1c(/C=C/[C@@H](O)C[C@@H](O)CC(=O)O)c(-c2ccc(F)cc2)c2ccccc21"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "432.2773 C19H39N5O7 Massbank:AU210231 Fluvastatin|(E,3R,5S)-7-[3-(4-fluorophenyl)-1-propan-2-ylindol-2-yl]-3,5-dihydroxyhept-6-enoic acid"

$Cons_Name_ClassyFire
[1] "432.2773 Pyrroles M+Na"

$`CAN_all classifications`
[1] "Organic compounds; Alcohols and polyols; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Monoalkylamines; 1,2-aminoalcohols; Alpha amino acid amides; Amines; Primary amines; Alkanolamines; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9402579

masst_results %>% 
  filter(FEATURE_ID == "X9402579") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9402579"

$PHYLA
[1] "Ascomycota, Cyanobacteria, Firmicutes, Spirochaetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9402579") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9402579"

$Cons_SMILES
[1] "CCC(=O)OC(OP(=O)(CCCCc1ccccc1)CC(=O)N1C[C@H](C2CCCCC2)C[C@H]1C(=O)O)C(C)C"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "564.3554 C25H51N5O10 Massbank:AU224709 Fosinopril|(2S,4S)-4-cyclohexyl-1-[2-[(2-methyl-1-propanoyloxypropoxy)-(4-phenylbutyl)phosphoryl]acetyl]pyrrolidine-2-carboxylic acid"

$Cons_Name_ClassyFire
[1] "564.3554 Carboxylic acids and derivatives M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Fatty amides; Monoalkylamines; Carboxylic acid amides; N-acyl amines; Secondary alcohols; Secondary carboxylic acid amides; Carbonyl compounds; Amines; Primary amines; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9402985

masst_results %>% 
  filter(FEATURE_ID == "X9402985") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9402985"

$PHYLA
[1] "Ascomycota, Cyanobacteria, Spirochaetes, Bacteroidetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9402985") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9402985"

$Cons_SMILES
[1] "CCC(=O)OC(OP(=O)(CCCCc1ccccc1)CC(=O)N1C[C@H](C2CCCCC2)C[C@H]1C(=O)O)C(C)C"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "608.3816 C22H47N15O4 Massbank:AU224709 Fosinopril|(2S,4S)-4-cyclohexyl-1-[2-[(2-methyl-1-propanoyloxypropoxy)-(4-phenylbutyl)phosphoryl]acetyl]pyrrolidine-2-carboxylic acid"

$Cons_Name_ClassyFire
[1] "608.3816 Carboxylic acids and derivatives M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Carboxylic acids and derivatives; Organonitrogen compounds; Organooxygen compounds; Fatty amides; Peptides; Guanidines; Monoalkylamines; Carboxylic acid amides; N-acyl amines; Secondary carboxylic acid amides; Alpha amino acid amides; Amines; Primary amines; Carboximidamides; Organic 1,3-dipolar compounds; Propargyl-type 1,3-dipolar organic compounds; Fatty Acyls; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9404602

masst_results %>% 
  filter(FEATURE_ID == "X9404602") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9404602"

$PHYLA
[1] "Bacteroidetes"
feature_info %>% 
  filter(MET_CHEM_NO == "X9404602") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9404602"

$Cons_SMILES
[1] "CCCCCCCCCCCCOCCOCCO"

$Cons_Highest_annot
[1] "SIRIUS_CSI"

$Cons_Name
[1] "275.2564 C16H34O3 Decyldiglycol"

$Cons_Name_ClassyFire
[1] "275.2564 Monoradylglycerols [M + H]+"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Glycerolipids; Organic acids and derivatives; Carboxylic acids and derivatives; Primary alcohols; Organooxygen compounds; Carboxylic acid derivatives; Monocarboxylic acids and derivatives; Carboxylic acid esters; Secondary alcohols; Carbonyl compounds; Polyols; Monoradylglycerols; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9405371

masst_results %>% 
  filter(FEATURE_ID == "X9405371") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9405371"

$PHYLA
[1] "Ascomycota, Actinobacteria, Cyanobacteria, Firmicutes, Spirochaetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9405371") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9405371"

$Cons_SMILES
[1] "C/C(CO)=C1/CCC23COC(C2)C(O)(C(=O)O)CCC13"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "300.1996 C11H27N5O3 (4E)-8-hydroxy-4-(1-hydroxypropan-2-ylidene)-10-oxatricyclo[7.2.1.0�,?]dodecane-8-carboxylic acid"

$Cons_Name_ClassyFire
[1] "300.1996 Hydroxy acids and derivatives [M+NH4]+"

$`CAN_all classifications`
[1] "Organic compounds; Alcohols and polyols; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Monoalkylamines; Amines; Primary amines; Alkanolamines; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9411450

masst_results %>% 
  filter(FEATURE_ID == "X9411450") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9411450"

$PHYLA
[1] "Chordata, Basidiomycota, Ascomycota, Cyanobacteria, Firmicutes, Bacteroidetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9411450") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9411450"

$Cons_SMILES
[1] "CCCCCCCCCCCCOCCOCCOCCOCCO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "380.3347 C16H38N6O3 Massbank:AU406501 3,6,9,12-Tetraoxatetracosan-1-ol|Tetraethylene glycol monododecyl ether|2-[2-[2-(2-dodecoxyethoxy)ethoxy]ethoxy]ethanol"

$Cons_Name_ClassyFire
[1] "380.3347 Organooxygen compounds M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Organonitrogen compounds; Organooxygen compounds; Fatty amides; Monoalkylamines; Amines; Primary amines; Fatty Acyls; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9412241

masst_results %>% 
  filter(FEATURE_ID == "X9412241") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9412241"

$PHYLA
[1] "Actinobacteria, Firmicutes, Spirochaetes, Bacteroidetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9412241") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9412241"

$Cons_SMILES
[1] NA

$Cons_Highest_annot
[1] "SIRIUS_CANOPUS"

$Cons_Name
[1] "740.4598 C30H59N15O8 Oligopeptides"

$Cons_Name_ClassyFire
[1] "740.4598 Oligopeptides [M - H2O + H]+"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Amino acids, peptides, and analogues; Alpha amino acids and derivatives; Alcohols and polyols; Fatty acids and conjugates; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Fatty amides; Amino acids and derivatives; Peptides; Guanidines; Monoalkylamines; Carboxylic acid amides; Carboxylic acid derivatives; N-acyl amines; N-acyl-alpha amino acids and derivatives; Carboxylic acids; Secondary carboxylic acid amides; Carbonyl compounds; Alpha amino acid amides; N-acyl-alpha amino acids; Benzenoids; Amines; Primary amines; Carboximidamides; Organic 1,3-dipolar compounds; Propargyl-type 1,3-dipolar organic compounds; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Amino acids; Serine and derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Oligopeptides; Chemical entities"

X9412614

masst_results %>% 
  filter(FEATURE_ID == "X9412614") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9412614"

$PHYLA
[1] "Chordata, Ascomycota, Cyanobacteria, Firmicutes, Spirochaetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9412614") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9412614"

$Cons_SMILES
[1] "CCCCCCCCOc1ccc(C(=O)c2ccccc2)c(O)c1"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "388.2515 C15H35N5O5 Octabenzone"

$Cons_Name_ClassyFire
[1] "388.2515 Benzene and substituted derivatives M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Ethers; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Fatty amides; Peptides; Monoalkylamines; N-acyl amines; Dialkyl ethers; Alpha amino acid amides; Amines; Primary amines; Fatty Acyls; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9413313

masst_results %>% 
  filter(FEATURE_ID == "X9413313") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9413313"

$PHYLA
[1] "Ascomycota, Cyanobacteria, Firmicutes, Spirochaetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9413313") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9413313"

$Cons_SMILES
[1] "OCCOCCOCCOCCOCCOCCO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "344.2258 C13H31N5O4 Hexaethylene glycol"

$Cons_Name_ClassyFire
[1] "344.2258 Organooxygen compounds M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Amino acids, peptides, and analogues; Alpha amino acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Organooxygen compounds; Fatty amides; Amino acids and derivatives; Peptides; Monoalkylamines; Carboxylic acid amides; Carboxylic acid derivatives; N-acyl amines; N-acyl-alpha amino acids and derivatives; Secondary carboxylic acid amides; Carbonyl compounds; Alpha amino acid amides; Amines; Primary amines; Fatty Acyls; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Dipeptides; Chemical entities"

X9413456

masst_results %>% 
  filter(FEATURE_ID == "X9413456") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9413456"

$PHYLA
[1] "Ascomycota, Actinobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9413456") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9413456"

$Cons_SMILES
[1] "C1CCC2OCCOCCOCCOC3CCCCC3OCCOCCOCCOC2C1"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "464.4281 C25H55N5O Dicyclohexano-24-crown-8"

$Cons_Name_ClassyFire
[1] "464.4281 Organooxygen compounds M+NH4"

$`CAN_all classifications`
[1] "Organic compounds; Organoheterocyclic compounds; Organonitrogen compounds; Organooxygen compounds; Azoles; Monoalkylamines; Amines; Primary amines; Cyclohexylamines; Azacyclic compounds; Heteroaromatic compounds; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9420364

masst_results %>% 
  filter(FEATURE_ID == "X9420364") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9420364"

$PHYLA
[1] "Chordata, Ascomycota, Verrucomicrobia, Actinobacteria, Cyanobacteria, Firmicutes, Bacteroidetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9420364") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9420364"

$Cons_SMILES
[1] "C1CCC2OCCOCCOCCOC3CCCCC3OCCOCCOCCOC2C1"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "408.3659 C23H47N5O2 Dicyclohexano-24-crown-8"

$Cons_Name_ClassyFire
[1] "408.3659 Organooxygen compounds M+H"

$`CAN_all classifications`
[1] "Organic compounds; Amino acids, peptides, and analogues; Alcohols and polyols; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Organooxygen compounds; Amino acids and derivatives; Monoalkylamines; Carboxylic acid amides; Carboxylic acid derivatives; Secondary carboxylic acid amides; Carbonyl compounds; Amines; Primary amines; Organic oxides; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9423545

masst_results %>% 
  filter(FEATURE_ID == "X9423545") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9423545"

$PHYLA
[1] "Actinobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9423545") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9423545"

$Cons_SMILES
[1] NA

$Cons_Highest_annot
[1] "SIRIUS_CANOPUS"

$Cons_Name
[1] "418.3857 C20H49N7O3 1,2-aminoalcohols"

$Cons_Name_ClassyFire
[1] "418.3857 1,2-aminoalcohols [M - H2O + H]+"

$`CAN_all classifications`
[1] "Organic compounds; Alcohols and polyols; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Guanidines; Monoalkylamines; 1,2-aminoalcohols; Amines; Primary amines; Alkanolamines; Carboximidamides; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9424117

masst_results %>% 
  filter(FEATURE_ID == "X9424117") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9424117"

$PHYLA
[1] "Arthropoda, Chordata, Ascomycota, Cyanobacteria, Firmicutes, Bacteroidetes"
feature_info %>% 
  filter(MET_CHEM_NO == "X9424117") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9424117"

$Cons_SMILES
[1] "CCCCCCCCCCCCOCCOCCOCCOCCO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "336.3081 C17H39N5 Massbank:AU406506 3,6,9,12-Tetraoxatetracosan-1-ol|Tetraethylene glycol monododecyl ether|2-[2-[2-(2-dodecoxyethoxy)ethoxy]ethoxy]ethanol"

$Cons_Name_ClassyFire
[1] "336.3081 Organooxygen compounds M+H"

$`CAN_all classifications`
[1] "Organic compounds; Organonitrogen compounds; Monoalkylamines; Amines; Primary amines; Hydrocarbon derivatives; Organopnictogen compounds; Organic nitrogen compounds; Chemical entities"

X9425174

masst_results %>% 
  filter(FEATURE_ID == "X9425174") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9425174"

$PHYLA
[1] "Ascomycota, Verrucomicrobia, Actinobacteria, Firmicutes, Bacteroidetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9425174") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9425174"

$Cons_SMILES
[1] "CCCCCCCCCCCCOCCOCCOCCOCCO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "422.3811 C22H49N5O Massbank:AU406506 3,6,9,12-Tetraoxatetracosan-1-ol|Tetraethylene glycol monododecyl ether|2-[2-[2-(2-dodecoxyethoxy)ethoxy]ethoxy]ethanol"

$Cons_Name_ClassyFire
[1] "422.3811 Organooxygen compounds M+H"

$`CAN_all classifications`
[1] "Organic compounds; Organonitrogen compounds; Organooxygen compounds; Monoalkylamines; Amines; Primary amines; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9427382

masst_results %>% 
  filter(FEATURE_ID == "X9427382") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9427382"

$PHYLA
[1] "Arthropoda, Chordata, Basidiomycota, Ascomycota, Cyanobacteria, Bacteroidetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9427382") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9427382"

$Cons_SMILES
[1] "CCCCCCCCCCCCOCCOCCOCCOCCO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "394.3494 C20H45N5O Massbank:AU406506 3,6,9,12-Tetraoxatetracosan-1-ol|Tetraethylene glycol monododecyl ether|2-[2-[2-(2-dodecoxyethoxy)ethoxy]ethoxy]ethanol"

$Cons_Name_ClassyFire
[1] "394.3494 Organooxygen compounds M+H"

$`CAN_all classifications`
[1] "Organic compounds; Organonitrogen compounds; Organooxygen compounds; Monoalkylamines; Amines; Primary amines; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9428222

masst_results %>% 
  filter(FEATURE_ID == "X9428222") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9428222"

$PHYLA
[1] "Ascomycota, Cyanobacteria, Firmicutes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9428222") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9428222"

$Cons_SMILES
[1] NA

$Cons_Highest_annot
[1] "SIRIUS_CANOPUS"

$Cons_Name
[1] "564.3519 C32H47N5O5 Alkyl aryl ethers"

$Cons_Name_ClassyFire
[1] "564.3519 Alkyl aryl ethers [M - H2O + H]+"

$`CAN_all classifications`
[1] "Organic compounds; Organoheterocyclic compounds; Pyrimidines and pyrimidine derivatives; Alkyl aryl ethers; Alcohols and polyols; Ethers; Organonitrogen compounds; Primary alcohols; Organooxygen compounds; Fatty amides; Carboxylic acid amides; Aminopyrimidines and derivatives; Diazines; Trialkylamines; Benzene and substituted derivatives; Benzenoids; Amines; Tertiary amines; Aralkylamines; Fatty Acyls; Azacyclic compounds; Heteroaromatic compounds; Hydrocarbon derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Chemical entities"

X9429529

masst_results %>% 
  filter(FEATURE_ID == "X9429529") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9429529"

$PHYLA
[1] "Arthropoda, Ascomycota, Cyanobacteria, Firmicutes, Bacteroidetes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9429529") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9429529"

$Cons_SMILES
[1] "CCCCCCCCCCCCOCCOCCOCCOCCO"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "377.323 C21H44O5 Massbank:AU406506 3,6,9,12-Tetraoxatetracosan-1-ol|Tetraethylene glycol monododecyl ether|2-[2-[2-(2-dodecoxyethoxy)ethoxy]ethoxy]ethanol"

$Cons_Name_ClassyFire
[1] "377.323 Organooxygen compounds M+H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Alcohols and polyols; Glycerolipids; Organic acids and derivatives; Carboxylic acids and derivatives; Primary alcohols; Organooxygen compounds; Triacylglycerols; Secondary alcohols; Polyols; Triradylcglycerols; Fatty Acyls; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X950167

X950167

masst_results %>% 
  filter(FAMILY_ID == "X950167") %>% 
  pivot_wider(FEATURE_ID, names_from = NAME, values_from = p.value.fdr, names_sort = T) %>% 
  arrange(FEATURE_ID)

X9500389

masst_results %>% 
  filter(FEATURE_ID == "X9500389") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9500389"

$PHYLA
[1] "Euglenozoa"
feature_info %>% 
  filter(MET_CHEM_NO == "X9500389") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9500389"

$Cons_SMILES
[1] "CCCCCCCCCCCCOCCOS(=O)(=O)O"

$Cons_Highest_annot
[1] "SIRIUS_CSI"

$Cons_Name
[1] "309.1732 C14H30O5S 26183-44-8 (Parent)"

$Cons_Name_ClassyFire
[1] "309.1732 Sulfuric acid monoesters [M - H]-"

$`CAN_all classifications`
[1] "Organic compounds; Ethers; Organic acids and derivatives; Organooxygen compounds; Organic sulfuric acids and derivatives; Dialkyl ethers; Sulfuric acid monoesters; Sulfuric acid esters; Alkyl sulfates; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9500391

masst_results %>% 
  filter(FEATURE_ID == "X9500391") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9500391"

$PHYLA
[1] "Euglenozoa"
feature_info %>% 
  filter(MET_CHEM_NO == "X9500391") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9500391"

$Cons_SMILES
[1] "CC(OS(=O)(=O)O)C1(O)CCC2C3CCC4=CC(=O)CCC4(C)C3CCC21C"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "337.2037 C16H34O5S 4-Pregnen-17.alpha., 20.beta.-diol-3-one-20-sulfate"

$Cons_Name_ClassyFire
[1] "337.2037 Steroids and steroid derivatives M-H"

$`CAN_all classifications`
[1] "Organic compounds; Organic acids and derivatives; Organooxygen compounds; Organic sulfuric acids and derivatives; Sulfuric acid monoesters; Sulfuric acid esters; Alkyl sulfates; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9500396

masst_results %>% 
  filter(FEATURE_ID == "X9500396") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9500396"

$PHYLA
[1] "Euglenozoa"
feature_info %>% 
  filter(MET_CHEM_NO == "X9500396") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9500396"

$Cons_SMILES
[1] "CC1C(OS(=O)(=O)O)CC2CC(C(O)c3cc(=O)[nH]c(=O)[nH]3)NC3=NCC1N32"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "353.1993 C16H34O6S Cylindrospermopsin"

$Cons_Name_ClassyFire
[1] "353.1993  M-H"

$`CAN_all classifications`
[1] "Organic compounds; Alcohols and polyols; Ethers; Organic acids and derivatives; Organooxygen compounds; Organic sulfuric acids and derivatives; Sulfuric acid monoesters; Secondary alcohols; Polyols; Sulfuric acid esters; Alkyl sulfates; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9502327

masst_results %>% 
  filter(FEATURE_ID == "X9502327") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9502327"

$PHYLA
[1] "Euglenozoa"
feature_info %>% 
  filter(MET_CHEM_NO == "X9502327") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9502327"

$Cons_SMILES
[1] "CC12C=CC(=O)C=C1CCC1C2C(O)CC2(C)C1CCC2(O)C(=O)COS(=O)(=O)O"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "365.2309 C18H38O5S Prednisolone 21-sulfate"

$Cons_Name_ClassyFire
[1] "365.2309 Steroids and steroid derivatives M-H"

$`CAN_all classifications`
[1] "Organic compounds; Organic acids and derivatives; Organooxygen compounds; Organic sulfuric acids and derivatives; Sulfuric acid monoesters; Sulfuric acid esters; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9502350

masst_results %>% 
  filter(FEATURE_ID == "X9502350") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9502350"

$PHYLA
[1] "Euglenozoa"
feature_info %>% 
  filter(MET_CHEM_NO == "X9502350") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9502350"

$Cons_SMILES
[1] "CN1[C@H](C[C@H](O)c2ccccc2)CCC[C@@H]1CC(=O)c1ccccc1"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "309.1717 C14H30O5S Lobeline Hydrochloride"

$Cons_Name_ClassyFire
[1] "309.1717 Organooxygen compounds [M-H]-"

$`CAN_all classifications`
[1] "Organic compounds; Ethers; Organic acids and derivatives; Organooxygen compounds; Organic sulfuric acids and derivatives; Dialkyl ethers; Sulfuric acid monoesters; Sulfuric acid esters; Alkyl sulfates; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X9506236

masst_results %>% 
  filter(FEATURE_ID == "X9506236") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9506236"

$PHYLA
[1] "Euglenozoa"
feature_info %>% 
  filter(MET_CHEM_NO == "X9506236") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9506236"

$Cons_SMILES
[1] "CC(OS(=O)(=O)O)C1(O)CCC2C3CCC4=CC(=O)CCC4(C)C3CCC21C"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "337.2027 C16H34O5S 4-Pregnen-17.alpha., 20.beta.-diol-3-one-20-sulfate"

$Cons_Name_ClassyFire
[1] "337.2027 Steroids and steroid derivatives M-H"

$`CAN_all classifications`
[1] "Organic compounds; Organic acids and derivatives; Organooxygen compounds; Organic sulfuric acids and derivatives; Sulfuric acid monoesters; Sulfuric acid esters; Alkyl sulfates; Organic oxides; Hydrocarbon derivatives; Organic oxygen compounds; Chemical entities"

X950477

X950477

masst_results %>% 
  filter(FAMILY_ID == "X950477") %>% 
  pivot_wider(FEATURE_ID, names_from = NAME, values_from = p.value.fdr, names_sort = T) %>% 
  arrange(FEATURE_ID)

X9503038

masst_results %>% 
  filter(FEATURE_ID == "X9503038") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9503038"

$PHYLA
[1] "Basidiomycota"
feature_info %>% 
  filter(MET_CHEM_NO == "X9503038") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9503038"

$Cons_SMILES
[1] "CC(C)CC(NC(=O)C(N)CCC(=O)O)C(=O)O"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "259.1282 C11H20N2O5 Glu-Leu"

$Cons_Name_ClassyFire
[1] "259.1282 Carboxylic acids and derivatives M-H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Amino acids, peptides, and analogues; Alpha amino acids and derivatives; Fatty acids and conjugates; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Organooxygen compounds; Fatty amides; Branched fatty acids; Dicarboxylic acids and derivatives; Amino acids and derivatives; Peptides; Monoalkylamines; Carboxylic acid amides; Amino fatty acids; Carboxylic acid derivatives; N-acyl amines; N-acyl-alpha amino acids and derivatives; Carboxylic acids; Secondary carboxylic acid amides; Carbonyl compounds; N-acyl-alpha amino acids; Alpha amino acids; Amines; Primary amines; Gamma-glutamyl amino acids; Methyl-branched fatty acids; Fatty Acyls; Organic oxides; N-acyl-L-alpha-amino acids; Hydrocarbon derivatives; Amino acids; Glutamine and derivatives; Glutamic acid and derivatives; Leucine and derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Dipeptides; Chemical entities"

X9503142

masst_results %>% 
  filter(FEATURE_ID == "X9503142") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9503142"

$PHYLA
[1] "Actinobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9503142") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9503142"

$Cons_SMILES
[1] "NC(CC(=O)O)C(=O)NCC(=O)O"

$Cons_Highest_annot
[1] "GNPS_LIBA"

$Cons_Name
[1] "245.1137 C10H18N2O5 .alpha.-L-Asp-Gly"

$Cons_Name_ClassyFire
[1] "245.1137 Carboxylic acids and derivatives M-H"

$`CAN_all classifications`
[1] "Organic compounds; Lipids and lipid-like molecules; Amino acids, peptides, and analogues; Alpha amino acids and derivatives; Fatty acids and conjugates; Organic acids and derivatives; Carboxylic acids and derivatives; Organonitrogen compounds; Organooxygen compounds; Fatty amides; Branched fatty acids; Dicarboxylic acids and derivatives; Amino acids and derivatives; Peptides; Monoalkylamines; Carboxylic acid amides; Carboxylic acid derivatives; N-acyl amines; N-acyl-alpha amino acids and derivatives; Carboxylic acids; Secondary carboxylic acid amides; Carbonyl compounds; Alpha amino acid amides; N-acyl-alpha amino acids; Amines; Primary amines; Methyl-branched fatty acids; Fatty Acyls; Organic oxides; Hydrocarbon derivatives; Amino acids; Aspartic acid and derivatives; Leucine and derivatives; Organopnictogen compounds; Organic oxygen compounds; Organic nitrogen compounds; Dipeptides; Chemical entities"

X970034

X970034

masst_results %>% 
  filter(FAMILY_ID == "X970034") %>% 
  pivot_wider(FEATURE_ID, names_from = NAME, values_from = p.value.fdr, names_sort = T) %>% 
  arrange(FEATURE_ID)

X9701864

masst_results %>% 
  filter(FEATURE_ID == "X9701864") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9701864"

$PHYLA
[1] "Euglenozoa"
feature_info %>% 
  filter(MET_CHEM_NO == "X9701864") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9701864"

$Cons_SMILES
[1] "CCCCCCCCCCCCCCCCCC(=O)OCC"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "311.2945 Stearic Acid ethyl ester"

$Cons_Name_ClassyFire
[1] "311.2945 Fatty Acyls M-H"

$`CAN_all classifications`
[1] NA

X9707384

masst_results %>% 
  filter(FEATURE_ID == "X9707384") %>% 
  group_by(FEATURE_ID) %>% 
  summarize(PHYLA = NAME %>% str_c(collapse = ", ")) %>% 
  as.list()
$FEATURE_ID
[1] "X9707384"

$PHYLA
[1] "Bacillariophyta, Basidiomycota, Ascomycota, Euglenozoa, Firmicutes, Proteobacteria"
feature_info %>% 
  filter(MET_CHEM_NO == "X9707384") %>% 
  select(MET_CHEM_NO, starts_with("Cons_"), `CAN_all classifications`) %>% 
  as.list()
$MET_CHEM_NO
[1] "X9707384"

$Cons_SMILES
[1] "CNc1ccccc1C(=O)OC1OC(C)C(O)C(O)C1O"

$Cons_Highest_annot
[1] "GNPS_LIB"

$Cons_Name
[1] "311.1705 C13H28O8 5S-HETE-d8"

$Cons_Name_ClassyFire
[1] "311.1705  M-H"

$`CAN_all classifications`
[1] NA

Session info

sessionInfo()
R version 4.1.2 (2021-11-01)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19044)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] broom_0.7.11    jsonlite_1.7.2  magrittr_2.0.1  forcats_0.5.1   stringr_1.4.0   dplyr_1.0.7     purrr_0.3.4     readr_2.1.1     tidyr_1.1.4    
[10] tibble_3.1.6    ggplot2_3.3.5   tidyverse_1.3.2

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.8          lubridate_1.8.0     assertthat_0.2.1    digest_0.6.29       utf8_1.2.2          R6_2.5.1            cellranger_1.1.0   
 [8] backports_1.4.1     reprex_2.0.1        evaluate_0.19       httr_1.4.2          pillar_1.6.4        rlang_0.4.12        googlesheets4_1.0.0
[15] readxl_1.3.1        rstudioapi_0.13     jquerylib_0.1.4     rmarkdown_2.11      labeling_0.4.2      googledrive_2.0.0   bit_4.0.4          
[22] munsell_0.5.0       tinytex_0.36        compiler_4.1.2      modelr_0.1.8        xfun_0.35           pkgconfig_2.0.3     htmltools_0.5.2    
[29] tidyselect_1.1.1    fansi_0.5.0         crayon_1.4.2        tzdb_0.2.0          dbplyr_2.1.1        withr_2.4.3         grid_4.1.2         
[36] gtable_0.3.0        lifecycle_1.0.1     DBI_1.1.2           scales_1.1.1        cli_3.1.0           stringi_1.7.6       vroom_1.5.7        
[43] farver_2.1.0        fs_1.5.2            xml2_1.3.3          ellipsis_0.3.2      generics_0.1.1      vctrs_0.3.8         tools_4.1.2        
[50] bit64_4.0.5         glue_1.6.0          hms_1.1.1           parallel_4.1.2      fastmap_1.1.0       yaml_2.2.1          colorspace_2.0-2   
[57] gargle_1.2.0        rvest_1.0.2         knitr_1.41          haven_2.4.3        
LS0tDQp0aXRsZTogIm1pY3JvYmVNQVNTVCBFbnJpY2htZW50IEFuYWx5c2lzIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rDQotLS0NCg0KYGBge3J9DQpybShsaXN0PWxzKGFsbD1UUlVFKSkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShtYWdyaXR0cikNCmxpYnJhcnkoanNvbmxpdGUpDQpsaWJyYXJ5KGJyb29tKQ0KYGBgDQoNClJlYWQgZXhhbXBsZSBqc29uIGZpbGU6DQpgYGB7cn0NCnJlc3VsdHNfZGlyIDwtICJtaWNyb2JlTUFTU1RfcmVzdWx0cy8iDQpqc29uX2V4YW1wbGUgPC0gcmVhZF9qc29uKHN0cl9jKHJlc3VsdHNfZGlyLCAiZmFzdE1BU1NUX0hJTElDX25lZ19fMTY1X21pY3JvYmUuanNvbiIpLCBzaW1wbGlmeVZlY3RvciA9IEYpDQpgYGANCg0KRGVmaW5lIGZ1bmN0aW9uIGZvciBpdGVyYXRpbmcgb3ZlciBub2RlcyBpbiB0aGUgTUFTU1Qgb3V0cHV0Og0KYGBge3J9DQppdGVyYXRlX21hc3N0IDwtIGZ1bmN0aW9uKG1hc3N0X25vZGUpew0KICBub2RlX2F0dHJpYnV0ZXMgPC0gbmFtZXMobWFzc3Rfbm9kZSkNCiAgaWYgKCJSYW5rIiAlaW4lIG5vZGVfYXR0cmlidXRlcyAmJiBtYXNzdF9ub2RlJFJhbmsgPT0gInBoeWx1bSIpIHsNCiAgICB0aWJibGUoDQogICAgICBOQU1FID0gbWFzc3Rfbm9kZSRuYW1lLCANCiAgICAgIFRZUEUgPSBtYXNzdF9ub2RlJHR5cGUsIA0KICAgICAgTkNCSSA9IG1hc3N0X25vZGUkTkNCSSwgDQogICAgICBSQU5LID0gbWFzc3Rfbm9kZSRSYW5rLCANCiAgICAgIEdST1VQX1NJWkUgPSBtYXNzdF9ub2RlJGdyb3VwX3NpemUsIA0KICAgICAgTUFUQ0hFRF9TSVpFID0gbWFzc3Rfbm9kZSRtYXRjaGVkX3NpemUNCiAgICAgICkNCiAgfQ0KICBlbHNlIHsNCiAgICBpZiAoInR5cGUiICVpbiUgbm9kZV9hdHRyaWJ1dGVzICYmIG1hc3N0X25vZGUkdHlwZSA9PSAibm9kZSIpIHsNCiAgICAgIGxhcHBseShtYXNzdF9ub2RlJGNoaWxkcmVuLCBpdGVyYXRlX21hc3N0KSAlPiUgDQogICAgICAgIGJpbmRfcm93cygpDQogICAgfQ0KICAgIGVsc2Ugew0KICAgICAgdGliYmxlKA0KICAgICAgICBOQU1FID0gY2hhcmFjdGVyKCksIA0KICAgICAgICBUWVBFID0gY2hhcmFjdGVyKCksIA0KICAgICAgICBOQ0JJID0gY2hhcmFjdGVyKCksIA0KICAgICAgICBSQU5LID0gY2hhcmFjdGVyKCksIA0KICAgICAgICBHUk9VUF9TSVpFID0gaW50ZWdlcigpLCANCiAgICAgICAgTUFUQ0hFRF9TSVpFID0gaW50ZWdlcigpDQogICAgICAgICkNCiAgICB9DQogIH0NCn0NCg0KaXRlcmF0ZV9tYXNzdChqc29uX2V4YW1wbGUpDQpgYGANCg0KU2V0IHVwIHRpYmJsZSBpbml0aWFsaXplZCB3aXRoIGFsbCBqc29uIGZpbGUgbmFtZXM6DQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgPC0gdGliYmxlKEZJTEVfTkFNRSA9IGRpcihyZXN1bHRzX2RpciwgIi4qXFwuanNvbiIpKQ0KDQptYXNzdF9yZXN1bHRzDQpgYGANCg0KUGFyc2UgaW5mbyBmcm9tIGZpbGUgbmFtZXM6DQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgPC0gbWFzc3RfcmVzdWx0cyAlPiUgDQogIG11dGF0ZSgNCiAgICBTRUFSQ0hfVFlQRSA9IEZJTEVfTkFNRSAlPiUgc3RyX2V4dHJhY3QoImZvb2R8bWljcm9iZSIpLA0KICAgIERBVEFTRVQgPSBGSUxFX05BTUUgJT4lIHN0cl9leHRyYWN0KCIoSElMSUN8UlApLisocG9zfG5lZykiKSwNCiAgICBEQVRBU0VUID0gaWZfZWxzZShEQVRBU0VUID09ICJSUF9uZWciLCAiUlAxOF9uZWciLCBEQVRBU0VUKSwNCiAgICBTQ0FOID0gRklMRV9OQU1FICU+JSBzdHJfZXh0cmFjdCgiX18uK18iKSAlPiUgc3RyX2V4dHJhY3QoIlswLTldKyIpLA0KICAgIEZFQVRVUkVfSUQgPSBzdHJfYygNCiAgICAgIGNhc2Vfd2hlbigNCiAgICAgICAgREFUQVNFVCA9PSAiUlAxOF9wb3MiICB+ICJYOTQiLA0KICAgICAgICBEQVRBU0VUID09ICJSUDE4X25lZyIgIH4gIlg5NSIsDQogICAgICAgIERBVEFTRVQgPT0gIkhJTElDX3BvcyIgfiAiWDk2IiwNCiAgICAgICAgREFUQVNFVCA9PSAiSElMSUNfbmVnIiB+ICJYOTciDQogICAgICApLA0KICAgICAgU0NBTiAlPiUgc3RyX3BhZChtYXgobmNoYXIoU0NBTikpLCAibGVmdCIsICIwIikNCiAgICApDQogICkNCg0KbWFzc3RfcmVzdWx0cw0KYGBgDQoNCk51bWJlciBvZiByZXN1bHRzIGZpbGVzIHBlciBkYXRhc2V0Og0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgY291bnQoREFUQVNFVCkNCmBgYA0KDQpSZWFkIGpzb24gZmlsZXMgZm9yIG1pY3JvYmVNQVNTVDoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyA8LSBtYXNzdF9yZXN1bHRzICU+JSANCiAgbXV0YXRlKA0KICAgIFBBVEggPSBzdHJfYyhyZXN1bHRzX2RpciwgRklMRV9OQU1FKSwNCiAgICBKU09OID0gUEFUSCAlPiUgbWFwKHJlYWRfanNvbiksDQogICAgU1RBVFNfUEhZTFVNID0gSlNPTiAlPiUgbWFwKGl0ZXJhdGVfbWFzc3QpDQogICkNCg0KbWFzc3RfcmVzdWx0cyRKU09OW1sxXV1bc2V0ZGlmZihuYW1lcyhtYXNzdF9yZXN1bHRzJEpTT05bWzFdXSksIGMoImNoaWxkcmVuIiwgInBpZV9kYXRhIikpXQ0KYGBgDQoNCkFkZCBzdGF0cyBmb3IgcGh5bHVtOg0KYGBge3J9DQptYXNzdF9yZXN1bHRzIDwtIG1hc3N0X3Jlc3VsdHMgJT4lIA0KICBtdXRhdGUoDQogICAgU1RBVFNfUk9PVCAgID0gSlNPTiAlPiUgbWFwKH4gdGliYmxlKFJPT1RfR1JPVVBfU0laRSA9IC4kZ3JvdXBfc2l6ZSwgUk9PVF9NQVRDSEVEX1NJWkUgPSAuJG1hdGNoZWRfc2l6ZSkpLA0KICAgIFNUQVRTX1BIWUxVTSA9IEpTT04gJT4lIG1hcChpdGVyYXRlX21hc3N0KQ0KICApDQoNCm1hc3N0X3Jlc3VsdHMkU1RBVFNfUk9PVFtbMV1dDQptYXNzdF9yZXN1bHRzJFNUQVRTX1BIWUxVTVtbMV1dDQpgYGANCg0KU2VsZWN0IHJlbGV2YW50IGNvbHVtbnMgYW5kIHVubmVzdCBzdGF0czoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyA8LSBtYXNzdF9yZXN1bHRzICU+JSANCiAgc2VsZWN0KEZFQVRVUkVfSUQsIERBVEFTRVQsIFNFQVJDSF9UWVBFLCBTVEFUU19ST09ULCBTVEFUU19QSFlMVU0pICU+JSANCiAgdW5uZXN0KGMoU1RBVFNfUk9PVCwgU1RBVFNfUEhZTFVNKSkNCg0KbWFzc3RfcmVzdWx0cw0KYGBgDQoNCkNoZWNrOiBJcyB0aGVyZSBhbnkgb3RoZXIgYFRZUEVgIHRoYW4gIm5vZGUiPw0KYGBge3J9DQptYXNzdF9yZXN1bHRzJFRZUEUgJT4lIHVuaXF1ZSgpDQpgYGANCg0KQ2hlY2s6IElzIHRoZXJlIGFueSBvdGhlciBgUkFOS2AgdGhhbiAicGh5bHVtIj8NCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyRSQU5LICU+JSB1bmlxdWUoKQ0KYGBgDQoNClBlcmZvcm0gRmlzaGVyJ3MgZXhhY3QgdGVzdCBmb3IgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gZmVhdHVyZXMgYW5kIHBoeWxhOg0KYGBge3J9DQptYXNzdF9yZXN1bHRzIDwtIG1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoTUFUQ0hFRF9TSVpFID4gMCkgJT4lIA0KICBtdXRhdGUoDQogICAgRklTSEVSID0gcG1hcCgNCiAgICAgIGxpc3QoDQogICAgICAgIFJPT1RfR1JPVVBfU0laRSwgDQogICAgICAgIFJPT1RfTUFUQ0hFRF9TSVpFLCANCiAgICAgICAgR1JPVVBfU0laRSwgDQogICAgICAgIE1BVENIRURfU0laRQ0KICAgICAgKSwNCiAgICAgIH4gZmlzaGVyLnRlc3QoDQogICAgICAgIG1hdHJpeCgNCiAgICAgICAgICBjKC4uMSwgLi4yLCAuLjMsIC4uNCksDQogICAgICAgICAgbnJvdyA9IDINCiAgICAgICAgKQ0KICAgICAgKQ0KICAgICksDQogICAgRklTSEVSID0gRklTSEVSICU+JSBtYXAodGlkeSkNCiAgKSAlPiUgDQogIHVubmVzdChGSVNIRVIpDQoNCm1hc3N0X3Jlc3VsdHMNCmBgYA0KDQpQZXJmb3JtIGNvcnJlY3Rpb24gZm9yIG11bHRpcGxlIHRlc3RpbmcgYW5kIGNoZWNrIGRpc3RyaWJ1dGlvbiBvZiBwLXZhbHVlczoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyA8LSBtYXNzdF9yZXN1bHRzICU+JSANCiAgbXV0YXRlKHAudmFsdWUuZmRyID0gcC52YWx1ZSAlPiUgcC5hZGp1c3QobWV0aG9kID0gImZkciIpKQ0KDQptYXNzdF9yZXN1bHRzICU+JSANCiAgZ2dwbG90KCkgKyANCiAgZ2VvbV9wb2ludChhZXMocC52YWx1ZSwgcC52YWx1ZS5mZHIpKSArDQogIGdlb21fYWJsaW5lKHNsb3BlID0gMSkNCg0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHAudmFsdWUuZmRyLCBmaWxsID0gREFUQVNFVCksIGJpbnMgPSAxMDApICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDA6NS81KQ0KDQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKHAudmFsdWUuZmRyIDwgMC4xKSAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHAudmFsdWUuZmRyLCBmaWxsID0gREFUQVNFVCksIGJpbnMgPSAxMDApICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDA6NS81MCkNCg0KbWFzc3RfcmVzdWx0cyAlPiUgDQogICAgZmlsdGVyKHAudmFsdWUuZmRyIDwgMC4wMSkgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGdlb21faGlzdG9ncmFtKGFlcyhwLnZhbHVlLmZkciwgZmlsbCA9IERBVEFTRVQpLCBiaW5zID0gMTAwKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAwOjUvNTAwKQ0KDQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKHAudmFsdWUuZmRyIDwgMC4wMDEpICU+JSANCiAgZ2dwbG90KCkgKw0KICBnZW9tX2hpc3RvZ3JhbShhZXMocC52YWx1ZS5mZHIsIGZpbGwgPSBEQVRBU0VUKSwgYmlucyA9IDEwMCkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gMDo1LzUwMDApDQpgYGANCg0KRmlsdGVyIGZvciBhIHAtdmFsdWUgPCAwLjAxOg0KYGBge3J9DQptYXNzdF9yZXN1bHRzIDwtIG1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIocC52YWx1ZS5mZHIgPCAwLjAxKQ0KDQptYXNzdF9yZXN1bHRzDQpgYGANCg0KTnVtYmVyIG9mIHNpZ25pZmljYW50IGhpdHMgcGVyIGRhdGFzZXQ6DQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBjb3VudChEQVRBU0VUKQ0KYGBgDQoNCk51bWJlciBvZiBzaWduaWZpY2FudCBoaXRzIHBlciBkYXRhc2V0Og0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZ3JvdXBfYnkoREFUQVNFVCkgJT4lIA0KICBzdW1tYXJpemUoTl9GRUFUVVJFUyA9IG5fZGlzdGluY3QoRkVBVFVSRV9JRCkpDQpgYGANCg0KRXhwb3J0IHNpZ25pZmljYW50IGhpdHMgZm9yIEN5dG9zY2FwZToNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIG11dGF0ZShgc2hhcmVkIG5hbWVgID0gRkVBVFVSRV9JRCAlPiUgc3RyX3N1YigtNSwgLTEpICU+JSBhcy5pbnRlZ2VyKCkpICU+JSANCiAgZ3JvdXBfYnkoREFUQVNFVCwgYHNoYXJlZCBuYW1lYCkgJT4lIA0KICBzdW1tYXJpemUoTUFTU1RfUEhZTEEgPSBOQU1FICU+JSBzb3J0KCkgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIiksIC5ncm91cHMgPSAiZHJvcF9sYXN0IikgJT4lIA0KICBuZXN0KCkgJT4lIA0KICBtdXRhdGUoDQogICAgRklMRV9OQU1FID0gREFUQVNFVCAlPiUgc3RyX3JlbW92ZSgiXyIpICU+JSBzdHJfYygiLnRzdiIpLA0KICAgIERVTU1ZID0gbWFwMihkYXRhLCBGSUxFX05BTUUsIH4gd3JpdGVfdHN2KC54LCAueSkpDQogICkNCmBgYA0KDQojIE1hcCBNQVNTVCByZXN1bHRzIGZyb20gZmVhdHVyZXMgdG8gZmFtaWxpZXMNCg0KUmVhZCBmZWF0dXJlIGFubm90YXRpb25zIGZyb20gZmlsZToNCmBgYHtyfQ0KZmVhdHVyZV9pbmZvIDwtIHJiaW5kKA0KICByZWFkX3RzdigiZmVhdHVyZV9tZXRhZGF0YS9DMThuZWdfZmVhdHVyZV9tZXRhZGF0YV9jb25zb2xpZGF0ZWRfaXNfbWljcm9iaWFsLnRzdiIsIGd1ZXNzX21heCA9IDEwMDAwMCkgJT4lIA0KICAgIG11dGF0ZShNRVRfQ0hFTV9OTyA9IHBhc3RlMCgiWDk1IiwgZm9ybWF0QyhgI2ZlYXR1cmVJRGAsICAgICAgICB3aWR0aCA9IDUsIGZsYWcgPSAiMCIsIGZvcm1hdCA9ICJkIikpKSAlPiUgDQogICAgbXV0YXRlKEZBTUlMWV9JRCAgID0gcGFzdGUwKCJYOTUiLCBmb3JtYXRDKEdOUFNfY29tcG9uZW50aW5kZXgsIHdpZHRoID0gNCwgZmxhZyA9ICIwIiwgZm9ybWF0ID0gImQiKSkpLA0KICByZWFkX3RzdigiZmVhdHVyZV9tZXRhZGF0YS9DMThwb3NfZmVhdHVyZV9tZXRhZGF0YV9jb25zb2xpZGF0ZWRfaXNfbWljcm9iaWFsLnRzdiIsIGd1ZXNzX21heCA9IDEwMDAwMCkgJT4lIA0KICAgIG11dGF0ZShNRVRfQ0hFTV9OTyA9IHBhc3RlMCgiWDk0IiwgZm9ybWF0QyhgI2ZlYXR1cmVJRGAsICAgICAgICB3aWR0aCA9IDUsIGZsYWcgPSAiMCIsIGZvcm1hdCA9ICJkIikpKSAlPiUgDQogICAgbXV0YXRlKEZBTUlMWV9JRCAgID0gcGFzdGUwKCJYOTQiLCBmb3JtYXRDKEdOUFNfY29tcG9uZW50aW5kZXgsIHdpZHRoID0gNCwgZmxhZyA9ICIwIiwgZm9ybWF0ID0gImQiKSkpLA0KICByZWFkX3RzdigiZmVhdHVyZV9tZXRhZGF0YS9ISUxJQ25lZ19mZWF0dXJlX21ldGFkYXRhX2NvbnNvbGlkYXRlZF9pc19taWNyb2JpYWwudHN2IiwgZ3Vlc3NfbWF4ID0gMTAwMDAwKSAlPiUgDQogICAgbXV0YXRlKE1FVF9DSEVNX05PID0gcGFzdGUwKCJYOTciLCBmb3JtYXRDKGAjZmVhdHVyZUlEYCwgICAgICAgIHdpZHRoID0gNSwgZmxhZyA9ICIwIiwgZm9ybWF0ID0gImQiKSkpICU+JSANCiAgICBtdXRhdGUoRkFNSUxZX0lEICAgPSBwYXN0ZTAoIlg5NyIsIGZvcm1hdEMoR05QU19jb21wb25lbnRpbmRleCwgd2lkdGggPSA0LCBmbGFnID0gIjAiLCBmb3JtYXQgPSAiZCIpKSksDQogIHJlYWRfdHN2KCJmZWF0dXJlX21ldGFkYXRhL0hJTElDcG9zX2ZlYXR1cmVfbWV0YWRhdGFfY29uc29saWRhdGVkX2lzX21pY3JvYmlhbC50c3YiLCBndWVzc19tYXggPSAxMDAwMDApICU+JSANCiAgICBtdXRhdGUoTUVUX0NIRU1fTk8gPSBwYXN0ZTAoIlg5NiIsIGZvcm1hdEMoYCNmZWF0dXJlSURgLCAgICAgICAgd2lkdGggPSA1LCBmbGFnID0gIjAiLCBmb3JtYXQgPSAiZCIpKSkgJT4lIA0KICAgIG11dGF0ZShGQU1JTFlfSUQgICA9IHBhc3RlMCgiWDk2IiwgZm9ybWF0QyhHTlBTX2NvbXBvbmVudGluZGV4LCB3aWR0aCA9IDQsIGZsYWcgPSAiMCIsIGZvcm1hdCA9ICJkIikpKQ0KICApICU+JSANCiAgbXV0YXRlKEZBTUlMWV9JRCA9IGlmX2Vsc2Uoc3RyX2RldGVjdChGQU1JTFlfSUQsICItMDAxJCIpLCAiU2luZ2xldG9uIiwgRkFNSUxZX0lEKSkNCmBgYA0KDQpBZGQgRkFNSUxZX0lEIHRvIHRoZSBNQVNTVCByZXN1bHRzOg0KYGBge3J9DQptYXNzdF9yZXN1bHRzIDwtIG1hc3N0X3Jlc3VsdHMgJT4lIA0KICBpbm5lcl9qb2luKA0KICAgIGZlYXR1cmVfaW5mbyAlPiUgDQogICAgICBzZWxlY3QoRkVBVFVSRV9JRCA9IE1FVF9DSEVNX05PLCBGQU1JTFlfSUQpDQogICkNCg0KbWFzc3RfcmVzdWx0cw0KYGBgDQoNCk51bWJlciBvZiBzaWduaWZpY2FudCBoaXRzIHBlciBkYXRhc2V0Og0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZ3JvdXBfYnkoREFUQVNFVCkgJT4lIA0KICBzdW1tYXJpemUoTl9GQU1JTElFUyA9IG5fZGlzdGluY3QoRkFNSUxZX0lEKSwgbiA9IG4oKSkNCmBgYA0KDQojIFN0YXRpc3RpY2FsIGFuYWx5c2lzIG9mIGZlYXR1cmVzDQoNClJlYWQgc3RhdGlzdGljYWwgcmVzdWx0cyBmcm9tIGZpbGU6DQpgYGB7cn0NCnNraW5fcF9jYXRfZGlyIDwtIHJlYWRfdHN2KCJVbnRhcmdldGVkLnBfY2F0X2Rpci50c3YiKQ0Kc2tpbl9wX3ZhbHVlICAgPC0gcmVhZF90c3YoIlVudGFyZ2V0ZWQucF92YWx1ZS50c3YiKQ0KYGBgDQoNCmBgYHtyfQ0Kc2tpbl9wX2NhdF9kaXIgJT4lIGNvbG5hbWVzKCkNCmBgYA0KDQoNCmBgYHtyfQ0Kc2tpbl9zdGF0cyA8LSBza2luX3BfdmFsdWUgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8pICU+JSANCiAgbGVmdF9qb2luKHNraW5fcF9jYXRfZGlyLCBieSA9ICJNRVRfQ0hFTV9OTyIpICU+JSANCiAgbXV0YXRlKA0KICAgIHNlYnVtZXRlcl8wLjFfYW55ICA9IGBwX2NhdF9kaXJ8YmFzZXxzZWJ1bWAgJT4lIGlzLm5hKC4pICU+JSBub3QoKSwNCiAgICBzZWJ1bWV0ZXJfMC4xX3VwICAgPSBgcF9jYXRfZGlyfGJhc2V8c2VidW1gICU+JSBpcy5uYSguKSAlPiUgbm90KCkgJiBgcF9jYXRfZGlyfGJhc2V8c2VidW1gICU+JSBzdHJfZGV0ZWN0KCJVcCIpLA0KICAgIHNlYnVtZXRlcl8wLjFfZG93biA9IGBwX2NhdF9kaXJ8YmFzZXxzZWJ1bWAgJT4lIGlzLm5hKC4pICU+JSBub3QoKSAmIGBwX2NhdF9kaXJ8YmFzZXxzZWJ1bWAgJT4lIHN0cl9kZXRlY3QoIkRuIikNCiAgKQ0KDQpza2luX3N0YXRzICU+JSANCiAgZ3JvdXBfYnkoYHBfY2F0X2RpcnxiYXNlfHNlYnVtYCwgc2VidW1ldGVyXzAuMV9hbnkpICU+JSBzdW1tYXJpemUoLmdyb3VwcyA9ICJkcm9wIikNCg0Kc2tpbl9zdGF0cyAlPiUgDQogIGdyb3VwX2J5KGBwX2NhdF9kaXJ8YmFzZXxzZWJ1bWAsIHNlYnVtZXRlcl8wLjFfdXApICU+JSBzdW1tYXJpemUoLmdyb3VwcyA9ICJkcm9wIikNCg0Kc2tpbl9zdGF0cyAlPiUgDQogIGdyb3VwX2J5KGBwX2NhdF9kaXJ8YmFzZXxzZWJ1bWAsIHNlYnVtZXRlcl8wLjFfZG93bikgJT4lIHN1bW1hcml6ZSguZ3JvdXBzID0gImRyb3AiKQ0KYGBgDQoNCkNoZWNrIHdoZXRoZXIgdGhlcmUgYXJlIHNraW4gc3RhdHMgZm9yIGFsbCBmZWF0dXJlcyBmcm9tIHRoZSBNQVNTVCByZXN1bHRzOg0KYGBge3J9DQptYXNzdF9yZXN1bHRzX3N0YXRzIDwtIG1hc3N0X3Jlc3VsdHMgJT4lIA0KICBpbm5lcl9qb2luKA0KICAgIHNraW5fc3RhdHMgJT4lIA0KICAgICAgc2VsZWN0KEZFQVRVUkVfSUQgPSBNRVRfQ0hFTV9OTywgc2VidW1ldGVyXzAuMV9hbnksIHNlYnVtZXRlcl8wLjFfdXAsIHNlYnVtZXRlcl8wLjFfZG93biksDQogICAgYnkgPSAiRkVBVFVSRV9JRCINCiAgKQ0KDQpzZXRkaWZmKG1hc3N0X3Jlc3VsdHMkRkVBVFVSRV9JRCwgc2tpbl9zdGF0cyRNRVRfQ0hFTV9OTykNCmBgYA0KDQoqIFllcw0KDQojIyBGZWF0dXJlcyBjb3JyZWxhdGVkIHdpdGggc2VidW1ldGVyIHNjb3JlDQoNCldoaWNoIGZlYXR1cmVzIHRoYXQgYXJlIHBvc2l0aXZlbHkgY29ycmVsYXRlZCB3aXRoIHNlYnVtZXRlciBzY29yZSBhcmUgYXNzb2NpYXRlZCB3aXRoIG1pY3JvYmVzPyBUaGUgZmlndXJlcyBpbiBlYWNoIHRhYmxlIGNhbGwgYXJlIHRoZSBmZHItY29ycmVjdGVkIHAtdmFsdWVzIGZvciB0aGUgYXNzb2NpYXRpb25zIGJldHdlZW4gZmVhdHVyZXMgYW5kIHBoeWxhOg0KYGBge3J9DQptYXNzdF9yZXN1bHRzX3N0YXRzICU+JSANCiAgZmlsdGVyKHNlYnVtZXRlcl8wLjFfdXApICU+JSANCiAgcGl2b3Rfd2lkZXIoYyhGRUFUVVJFX0lELCBEQVRBU0VUKSwgbmFtZXNfZnJvbSA9IE5BTUUsIHZhbHVlc19mcm9tID0gcC52YWx1ZS5mZHIpDQpgYGANCg0KV2hpY2ggZmVhdHVyZXMgdGhhdCBhcmUgbmVnYXRpdmVseSBjb3JyZWxhdGVkIHdpdGggc2VidW1ldGVyIHNjb3JlIGFyZSBhc3NvY2lhdGVkIHdpdGggbWljcm9iZXM/IFRoZSBmaWd1cmVzIGluIGVhY2ggdGFibGUgY2FsbCBhcmUgdGhlIGZkci1jb3JyZWN0ZWQgcC12YWx1ZXMgZm9yIHRoZSBhc3NvY2lhdGlvbnMgYmV0d2VlbiBmZWF0dXJlcyBhbmQgcGh5bGE6DQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHNfc3RhdHMgJT4lIA0KICBmaWx0ZXIoc2VidW1ldGVyXzAuMV9kb3duKSAlPiUgDQogIHBpdm90X3dpZGVyKGMoRkVBVFVSRV9JRCwgREFUQVNFVCksIG5hbWVzX2Zyb20gPSBOQU1FLCB2YWx1ZXNfZnJvbSA9IHAudmFsdWUuZmRyKQ0KYGBgDQoNCiMjIEVucmljaG1lbnQgYW5hbHlzaXMgb2YgZmVhdHVyZXMNCg0KKiBBcmUgdGhlIGZlYXR1cmVzIGFzc29jaWF0ZWQgd2l0aCBhIHBhcnRpY3VsYXIgcGh5bHVtIGVucmljaGVkIGluIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIGNvcnJlbGF0aW9ucyB3aXRoIHNlYnVtZXRlciBzY29yZT8NCiAgKyBOdWxsIGh5cG90aGVzaXM6IEFsbCBmZWF0dXJlcyBhc3NvY2lhdGVkIHdpdGggYSBwYXJ0aWN1bGFyIHBoeWx1bSBhcmUgdW5jb3JyZWxhdGVkIHdpdGggc2VidW1ldGVyIHNjb3JlLg0KICArIENhbiBiZSB0ZXN0ZWQgYnkgdGFraW5nIHRoZSBhbHBoYSBlcnJvciByYXRlIHRoYXQgd2FzIHVzZWQgd2hlbiB0ZXN0aW5nIGZvciBjb3JyZWxhdGlvbiBhbmQgYXNzdW1pbmcgYSBiaW5vbWlhbCBkaXN0cmlidXRpb24gYWNyb3NzIGFsbCBmZWF0dXJlcyBhc3NvY2lhdGVkIHdpdGggdGhhdCBwaHlsdW0uDQogICsgTmVlZHMgdGhlIHRvdGFsIG51bWJlciBvZiBmZWF0dXJlcywgYnV0IG5vdCB0aGUgdG90YWwgbnVtYmVyIG9mIHBoeWxhLg0KDQpDYWxjdWxhdGlvbiBvZiBiaW5vbWlhbCBkaXN0cmlidXRpb246DQoNCiogTl9GRUFUVVJFUzogTnVtYmVyIG9mIGZlYXR1cmVzIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXNwZWN0aXZlIHBoeWx1bSwgcmVnYXJkbGVzcyBvZiB0aGVpciBjb3JyZWxhdGlvbiB3aXRoIHNlYnVtZXRlciBzY29yZQ0KKiBOX0FOWTogTnVtYmVyIG9mIGZlYXR1cmVzIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXNwZWN0aXZlIHBoeWx1bSAqYW5kKiBzaWduaWZpY2FudGx5IGNvcnJlbGF0ZWQgd2l0aCBzZWJ1bWV0ZXIgc2NvcmUsIHJlZ2FyZGxlc3Mgb2YgZGlyZWN0aW9uDQoqIE5fUE9TOiBOdW1iZXIgb2YgZmVhdHVyZXMgc2lnbmlmaWNhbnRseSBhc3NvY2lhdGVkIHdpdGggdGhlIHJlc3BlY3RpdmUgcGh5bHVtICphbmQqIHBvc2l0aXZlbHkgY29ycmVsYXRlZCB3aXRoIHNlYnVtZXRlciBzY29yZQ0KKiBOX05FRzogTnVtYmVyIG9mIGZlYXR1cmVzIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXNwZWN0aXZlIHBoeWx1bSAqYW5kKiBuZWdhdGl2ZWx5IGNvcnJlbGF0ZWQgd2l0aCBzZWJ1bWV0ZXIgc2NvcmUNCg0KVGhlIGJpbm9taWFsIGRpc3RyaWJ1dGlvbiBnaXZlcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCB0aGUgb2JzZXJ2ZWQgb3IgYSBoaWdoZXIgbnVtYmVyIG9mIGZlYXR1cmVzIGlzIGNvcnJlbGF0ZWQgd2l0aCBzZWJ1bWV0ZXIgc2NvcmUganVzdCBieSBjaGFuY2UgKGZhbHNlIHBvc2l0aXZlcykuDQpgYGB7cn0NCnBfYWxwaGEgPC0gMC4xDQoNCm1hc3N0X3Jlc3VsdHNfc3RhdHMgJT4lIA0KICBncm91cF9ieShOQU1FKSAlPiUgDQogIHN1bW1hcml6ZSgNCiAgICBOX0ZFQVRVUkVTID0gbigpLA0KICAgIE5fQU5ZICAgICAgPSBzdW0oc2VidW1ldGVyXzAuMV9hbnkpLA0KICAgIE5fUE9TICAgICAgPSBzdW0oc2VidW1ldGVyXzAuMV91cCksDQogICAgTl9ORUcgICAgICA9IHN1bShzZWJ1bWV0ZXJfMC4xX2Rvd24pDQogICkgJT4lIA0KICByb3d3aXNlKCkgJT4lIA0KICBtdXRhdGUoDQogICAgUEJJTk9NX0FOWSA9IHBiaW5vbShOX0FOWSwgTl9GRUFUVVJFUywgcF9hbHBoYSwgbG93ZXIudGFpbCA9IEYpICU+JSBmb3JtYXQoZGlnaXRzID0gMiksDQogICAgUEJJTk9NX1BPUyA9IHBiaW5vbShOX1BPUywgTl9GRUFUVVJFUywgcF9hbHBoYSwgbG93ZXIudGFpbCA9IEYpICU+JSBmb3JtYXQoZGlnaXRzID0gMiksDQogICAgUEJJTk9NX05FRyA9IHBiaW5vbShOX05FRywgTl9GRUFUVVJFUywgcF9hbHBoYSwgbG93ZXIudGFpbCA9IEYpICU+JSBmb3JtYXQoZGlnaXRzID0gMikNCiAgKQ0KYGBgDQoNCiogQSBzaWduaWZpY2FudCBlbnJpY2htZW50IGlzIGZvdW5kIG9ubHkgZm9yIHBoeWxhIHdpdGggZmV3IGFzc29jaWF0ZWQgZmVhdHVyZXM6DQogICsgQmFjaWxsYXJpb3BoeXRhIHNob3cgYSBzaWduaWZpY2FudCBlbnJpY2htZW50IG9mIGFzc29jaWF0ZWQgZmVhdHVyZXMgd2hpY2ggYXJlICpuZWdhdGl2ZWx5KiBjb3JyZWxhdGVkIHdpdGggc2VidW1ldGVyIHNjb3JlDQogICsgRXVnbGVub3pvYSBzaG93IGEgc2lnbmlmaWNhbnQgZW5yaWNobWVudCBvZiBhc3NvY2lhdGVkIGZlYXR1cmVzIHdoaWNoIGFyZSAqbmVnYXRpdmVseSogY29ycmVsYXRlZCB3aXRoIHNlYnVtZXRlciBzY29yZQ0KDQpBcmUgdGhlc2UgZW5yaWNobWVudHMgZmFsc2UgcG9zaXRpdmVzLCBvciBhcmUgc2lnbmlmaWNhbnQgY29ycmVsYXRpb25zIHdpdGggc2VidW1ldGVyIHNjb3JlIGRpbHV0ZWQgYnkgc3RhdGlzdGljYWwgbm9pc2UgaW4gdGhlIHBoeWxhIHdpdGggbWFueSBhc3NvY2lhdGVkIGZlYXR1cmVzPw0KICANCiMgU3RhdGlzdGljYWwgYW5hbHlzaXMgb2YgZmFtaWxpZXMNCg0KUmVhZCBzdGF0aXN0aWNhbCByZXN1bHRzIGZyb20gZmlsZToNCmBgYHtyfQ0Kc2tpbl9wX2NhdF9kaXIgPC0gcmVhZF90c3YoIkFnZ3JlZ2F0ZWRfcF9jYXRfZGlyLnRzdiIpDQpza2luX3BfdmFsdWUgICA8LSByZWFkX3RzdigiQWdncmVnYXRlZF9wX3ZhbHVlLnRzdiIpDQpgYGANCg0KYGBge3J9DQpza2luX3BfY2F0X2RpciAlPiUgY29sbmFtZXMoKQ0KYGBgDQoNCg0KYGBge3J9DQpza2luX3N0YXRzIDwtIHNraW5fcF92YWx1ZSAlPiUgDQogIHNlbGVjdChGQU1JTFlfSUQpICU+JSANCiAgbGVmdF9qb2luKHNraW5fcF9jYXRfZGlyLCBieSA9ICJGQU1JTFlfSUQiKSAlPiUgDQogIG11dGF0ZSgNCiAgICBzZWJ1bWV0ZXJfMC4xX2FueSAgPSBgcF9jYXRfZGlyfGJhc2V8c2VidW1gICU+JSBpcy5uYSguKSAlPiUgbm90KCksDQogICAgc2VidW1ldGVyXzAuMV91cCAgID0gYHBfY2F0X2RpcnxiYXNlfHNlYnVtYCAlPiUgaXMubmEoLikgJT4lIG5vdCgpICYgYHBfY2F0X2RpcnxiYXNlfHNlYnVtYCAlPiUgc3RyX2RldGVjdCgiVXAiKSwNCiAgICBzZWJ1bWV0ZXJfMC4xX2Rvd24gPSBgcF9jYXRfZGlyfGJhc2V8c2VidW1gICU+JSBpcy5uYSguKSAlPiUgbm90KCkgJiBgcF9jYXRfZGlyfGJhc2V8c2VidW1gICU+JSBzdHJfZGV0ZWN0KCJEbiIpDQogICkNCg0Kc2tpbl9zdGF0cyAlPiUgDQogIGdyb3VwX2J5KGBwX2NhdF9kaXJ8YmFzZXxzZWJ1bWAsIHNlYnVtZXRlcl8wLjFfYW55KSAlPiUgc3VtbWFyaXplKC5ncm91cHMgPSAiZHJvcCIpDQoNCnNraW5fc3RhdHMgJT4lIA0KICBncm91cF9ieShgcF9jYXRfZGlyfGJhc2V8c2VidW1gLCBzZWJ1bWV0ZXJfMC4xX3VwKSAlPiUgc3VtbWFyaXplKC5ncm91cHMgPSAiZHJvcCIpDQoNCnNraW5fc3RhdHMgJT4lIA0KICBncm91cF9ieShgcF9jYXRfZGlyfGJhc2V8c2VidW1gLCBzZWJ1bWV0ZXJfMC4xX2Rvd24pICU+JSBzdW1tYXJpemUoLmdyb3VwcyA9ICJkcm9wIikNCmBgYA0KDQpBZ2dyZWdhdGUgYnkgcGh5bHVtIGFuZCBmYW1pbHk6DQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHNfZmFtaWx5IDwtIG1hc3N0X3Jlc3VsdHMgJT4lIA0KICBncm91cF9ieShOQU1FLCBGQU1JTFlfSUQpICU+JSANCiAgc3VtbWFyaXplKE5fRkVBVFVSRVMgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQoNCm1hc3N0X3Jlc3VsdHNfZmFtaWx5DQpgYGANCg0KQ2hlY2sgd2hldGhlciB0aGVyZSBhcmUgc2tpbiBzdGF0cyBmb3IgYWxsIGZhbWlsaWVzIGZyb20gdGhlIE1BU1NUIHJlc3VsdHM6DQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHNfc3RhdHMgPC0gbWFzc3RfcmVzdWx0c19mYW1pbHkgJT4lIA0KICBpbm5lcl9qb2luKA0KICAgIHNraW5fc3RhdHMgJT4lIA0KICAgICAgc2VsZWN0KEZBTUlMWV9JRCwgc2VidW1ldGVyXzAuMV9hbnksIHNlYnVtZXRlcl8wLjFfdXAsIHNlYnVtZXRlcl8wLjFfZG93biksDQogICAgYnkgPSAiRkFNSUxZX0lEIg0KICApDQoNCnNldGRpZmYobWFzc3RfcmVzdWx0cyRGQU1JTFlfSUQsIHNraW5fc3RhdHMkRkFNSUxZX0lEKQ0KYGBgDQoNCiogU29tZSBmYW1pbGllcyBmcm9tIHRoZSBNQVNTVCByZXN1bHRzIGFyZSBtaXNzaW5nIGZyb20gdGhlIHNraW4gc3RhdHMuDQoNCldoeSBhcmUgdGhlc2UgZmFtaWxpZXMgbWlzc2luZz8NCmBgYHtyfQ0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKEZBTUlMWV9JRCAlaW4lIGMoIlg5NzA4ODUiLCAiWDk2MTg2NCIsICJYOTUwNDY4IiwgIlg5NDAwNTciKSkgJT4lIA0KICBjb3VudChGQU1JTFlfSUQpDQpgYGANCg0KKiBUaGVzZSBmYW1pbGllcyBvbmx5IHR3byBub2RlcywgYnV0IGFnZ3JlZ2F0aW9uIHdhcyBwZXJmb3JtZWQgb25seSBmb3IgZmFtaWxpZXMgd2l0aCB0aHJlZSBvciBtb3JlIG5vZGVzLg0KDQojIyBGYW1pbGllcyBjb3JyZWxhdGVkIHdpdGggc2VidW1ldGVyIHNjb3JlDQoNCldoaWNoIGZhbWlsaWVzIHRoYXQgYXJlIHBvc2l0aXZlbHkgY29ycmVsYXRlZCB3aXRoIHNlYnVtZXRlciBzY29yZSBhcmUgYXNzb2NpYXRlZCB3aXRoIG1pY3JvYmVzPyBUaGUgZmlndXJlcyBpbiBlYWNoIHRhYmxlIGNhbGwgYXJlIHRoZSBudW1iZXIgb2YgZmVhdHVyZXMgZnJvbSB0aGF0IGZhbWlseSB3aGljaCBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXNwZWN0aXZlIHBoeWx1bToNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0c19zdGF0cyAlPiUgDQogIGZpbHRlcihzZWJ1bWV0ZXJfMC4xX3VwKSAlPiUgDQogIGlubmVyX2pvaW4oDQogICAgZmVhdHVyZV9pbmZvICU+JSANCiAgICAgIGNvdW50KEZBTUlMWV9JRCksDQogICAgYnkgPSAiRkFNSUxZX0lEIg0KICApICU+JSANCiAgcGl2b3Rfd2lkZXIoYyhGQU1JTFlfSUQsIG4pLCBuYW1lc19mcm9tID0gTkFNRSwgdmFsdWVzX2Zyb20gPSBOX0ZFQVRVUkVTLCBuYW1lc19zb3J0ID0gVCkgJT4lIA0KICBhcnJhbmdlKEZBTUlMWV9JRCkNCmBgYA0KDQoqIFg5NDAwMjkgaXMgYSBiaWcgZmFtaWx5IGNvbXByaXNpbmcgOTkgZmVhdHVyZXMsIG9mIHdoaWNoIHNldmVyYWwgYXJlIGFzc29jaWF0ZWQgd2l0aCBkaWZmZXJlbnQgcGh5bGEuICoqVGhpcyBmYW1pbHkgaXMgaW50ZXJlc3RpbmcuKioNCiogWDk1MDE5MCBpcyBhIG1lZGl1bS1zaXplIGZhbWlseSBjb21wcmlzaW5nIDIyIGZlYXR1cmVzLCBvZiB3aGljaCBvbmx5IG9uZSBpcyBhc3NvY2lhdGVkIHdpdGggQmFzaWRpb215Y290YS4NCg0KV2hpY2ggZmFtaWxpZXMgdGhhdCBhcmUgcG9zaXRpdmVseSBjb3JyZWxhdGVkIHdpdGggc2VidW1ldGVyIHNjb3JlIGFyZSBhc3NvY2lhdGVkIHdpdGggbWljcm9iZXM/IFRoZSBmaWd1cmVzIGluIGVhY2ggdGFibGUgY2FsbCBhcmUgdGhlIG51bWJlciBvZiBmZWF0dXJlcyBmcm9tIHRoYXQgZmFtaWx5IHdoaWNoIGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHJlc3BlY3RpdmUgcGh5bHVtOg0KYGBge3J9DQptYXNzdF9yZXN1bHRzX3N0YXRzICU+JSANCiAgZmlsdGVyKHNlYnVtZXRlcl8wLjFfZG93bikgJT4lIA0KICBpbm5lcl9qb2luKA0KICAgIGZlYXR1cmVfaW5mbyAlPiUgDQogICAgICBjb3VudChGQU1JTFlfSUQpLA0KICAgIGJ5ID0gIkZBTUlMWV9JRCINCiAgKSAlPiUgDQogIHBpdm90X3dpZGVyKGMoRkFNSUxZX0lELCBuKSwgbmFtZXNfZnJvbSA9IE5BTUUsIHZhbHVlc19mcm9tID0gTl9GRUFUVVJFUywgbmFtZXNfc29ydCA9IFQpICU+JSANCiAgYXJyYW5nZShGQU1JTFlfSUQpDQpgYGANCg0KKiBYOTQwMDA1IGlzIGEgYmlnIGZhbWlseSBjb21wcmlzaW5nIDg2IGZlYXR1cmVzLCBvZiB3aGljaCBzZXZlcmFsIGFyZSBhc3NvY2lhdGVkIHdpdGggZGlmZmVyZW50IHBoeWxhLiAqKlRoaXMgZmFtaWx5IGlzIGludGVyZXN0aW5nLioqDQoqIFg5NTA0NzcgaXMgYSBtZWRpdW0tc2l6ZSBmYW1pbHkgY29tcHJpc2luZyAxNyBmZWF0dXJlcywgb2Ygd2hpY2ggb25lIGlzIGFzc29jaWF0ZWQgd2l0aCBBY3Rpbm9iYWN0ZXJpYSBhbmQgb25lIHdpdGggQmFzaWRpb215Y290YSAoY291bGQgYmUgdGhlIHNhbWUgZmVhdHVyZSkuDQoqIFg5NzAwMzQgaXMgYSBtZWRpdW0tc2l6ZSBmYW1pbHkgY29tcHJpc2luZyAxNyBmZWF0dXJlcywgb2Ygd2hpY2ggb25lIGlzIGFzc29jaWF0ZWQgd2l0aCBBc2NvbXljb3RhIGFuZCBvbmUgd2l0aCBCYWNpbGxhcmlvcGh5dGEgKGNvdWxkIGJlIHRoZSBzYW1lIGZlYXR1cmUpLg0KKiBYOTUwMTY3IGlzIGEgbWVkaXVtLXNpemUgZmFtaWx5IGNvbXByaXNpbmcgMTYgZmVhdHVyZXMsIG9mIHdoaWNoIDYgYXJlIGFzc29jaWF0ZWQgd2l0aCBFdWdsZW5vem9hLiAqKlRoaXMgbWF5IGJlIGludGVyZXN0aW5nLCBidXQgdGhlIHJvbGUgb2YgZXVnbGVub3pvYSBvbiB0aGUgc2tpbiBpcyB1bmNsZWFyIHRvIG1lLioqIEhvd2V2ZXIgc2VlIGh0dHBzOi8vcm95YWxzb2NpZXR5cHVibGlzaGluZy5vcmcvZG9pLzEwLjEwOTgvcnNvYi4yMDA0MDcNCg0KIyMgRW5yaWNobWVudCBhbmFseXNpcyBvZiBmYW1pbGllcw0KDQoqIEFyZSB0aGUgZmVhdHVyZXMgYXNzb2NpYXRlZCB3aXRoIGEgcGFydGljdWxhciBwaHlsdW0gZW5yaWNoZWQgaW4gcG9zaXRpdmUgb3IgbmVnYXRpdmUgY29ycmVsYXRpb25zIHdpdGggc2VidW1ldGVyIHNjb3JlPw0KICArIE51bGwgaHlwb3RoZXNpczogQWxsIGZlYXR1cmVzIGFzc29jaWF0ZWQgd2l0aCBhIHBhcnRpY3VsYXIgcGh5bHVtIGFyZSB1bmNvcnJlbGF0ZWQgd2l0aCBzZWJ1bWV0ZXIgc2NvcmUuDQogICsgQ2FuIGJlIHRlc3RlZCBieSB0YWtpbmcgdGhlIGFscGhhIGVycm9yIHJhdGUgdGhhdCB3YXMgdXNlZCB3aGVuIHRlc3RpbmcgZm9yIGNvcnJlbGF0aW9uIGFuZCBhc3N1bWluZyBhIGJpbm9taWFsIGRpc3RyaWJ1dGlvbiBhY3Jvc3MgYWxsIGZlYXR1cmVzIGFzc29jaWF0ZWQgd2l0aCB0aGF0IHBoeWx1bS4NCiAgKyBOZWVkcyB0aGUgdG90YWwgbnVtYmVyIG9mIGZlYXR1cmVzLCBidXQgbm90IHRoZSB0b3RhbCBudW1iZXIgb2YgcGh5bGEuDQoNCkNhbGN1bGF0aW9uIG9mIGJpbm9taWFsIGRpc3RyaWJ1dGlvbjoNCg0KKiBOX0ZFQVRVUkVTOiBOdW1iZXIgb2YgZmVhdHVyZXMgc2lnbmlmaWNhbnRseSBhc3NvY2lhdGVkIHdpdGggdGhlIHJlc3BlY3RpdmUgcGh5bHVtLCByZWdhcmRsZXNzIG9mIHRoZWlyIGNvcnJlbGF0aW9uIHdpdGggc2VidW1ldGVyIHNjb3JlDQoqIE5fRkFNSUxJRVM6IE51bWJlciBvZiBmYW1pbGllcyBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVzcGVjdGl2ZSBwaHlsdW0sIHJlZ2FyZGxlc3Mgb2YgdGhlaXIgY29ycmVsYXRpb24gd2l0aCBzZWJ1bWV0ZXIgc2NvcmUNCiogTl9BTlk6IE51bWJlciBvZiBmYW1pbGllcyBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVzcGVjdGl2ZSBwaHlsdW0gKmFuZCogc2lnbmlmaWNhbnRseSBjb3JyZWxhdGVkIHdpdGggc2VidW1ldGVyIHNjb3JlLCByZWdhcmRsZXNzIG9mIGRpcmVjdGlvbg0KKiBOX1BPUzogTnVtYmVyIG9mIGZhbWlsaWVzIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXNwZWN0aXZlIHBoeWx1bSAqYW5kKiBwb3NpdGl2ZWx5IGNvcnJlbGF0ZWQgd2l0aCBzZWJ1bWV0ZXIgc2NvcmUNCiogTl9ORUc6IE51bWJlciBvZiBmYW1pbGllcyBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVzcGVjdGl2ZSBwaHlsdW0gKmFuZCogbmVnYXRpdmVseSBjb3JyZWxhdGVkIHdpdGggc2VidW1ldGVyIHNjb3JlDQoNClRoZSBiaW5vbWlhbCBkaXN0cmlidXRpb24gZ2l2ZXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgdGhlIG9ic2VydmVkIG9yIGEgaGlnaGVyIG51bWJlciBvZiBmYW1pbGllcyBpcyBjb3JyZWxhdGVkIHdpdGggc2VidW1ldGVyIHNjb3JlIGp1c3QgYnkgY2hhbmNlIChmYWxzZSBwb3NpdGl2ZXMpLg0KYGBge3J9DQpwX2FscGhhIDwtIDAuMQ0KDQptYXNzdF9yZXN1bHRzX3N0YXRzICU+JSANCiAgZ3JvdXBfYnkoTkFNRSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgTl9GRUFUVVJFUyA9IHN1bShOX0ZFQVRVUkVTKSwNCiAgICBOX0ZBTUlMSUVTID0gbigpLA0KICAgIE5fQU5ZICAgICAgPSBzdW0oc2VidW1ldGVyXzAuMV9hbnkpLA0KICAgIE5fUE9TICAgICAgPSBzdW0oc2VidW1ldGVyXzAuMV91cCksDQogICAgTl9ORUcgICAgICA9IHN1bShzZWJ1bWV0ZXJfMC4xX2Rvd24pDQogICkgJT4lIA0KICByb3d3aXNlKCkgJT4lIA0KICBtdXRhdGUoDQogICAgUEJJTk9NX0NIQU5HRUQgPSBwYmlub20oTl9BTlksIE5fRkFNSUxJRVMsIHBfYWxwaGEsIGxvd2VyLnRhaWwgPSBGKSAlPiUgZm9ybWF0KGRpZ2l0cyA9IDIpLA0KICAgIFBCSU5PTV9VUCAgICAgID0gcGJpbm9tKE5fUE9TLCBOX0ZBTUlMSUVTLCBwX2FscGhhLCBsb3dlci50YWlsID0gRikgJT4lIGZvcm1hdChkaWdpdHMgPSAyKSwNCiAgICBQQklOT01fRE9XTiAgICA9IHBiaW5vbShOX05FRywgTl9GQU1JTElFUywgcF9hbHBoYSwgbG93ZXIudGFpbCA9IEYpICU+JSBmb3JtYXQoZGlnaXRzID0gMikNCiAgKQ0KYGBgDQoNCiogQSBzaWduaWZpY2FudCBlbnJpY2htZW50IGlzIGZvdW5kIG9ubHkgZm9yIHBoeWxhIHdpdGggZmV3IGFzc29jaWF0ZWQgZmFtaWxpZXM6DQogICsgU3Bpcm9jaGFldGVzIHNob3cgYSBzaWduaWZpY2FudCBlbnJpY2htZW50IG9mIGFzc29jaWF0ZWQgZmVhdHVyZXMgd2hpY2ggYXJlICpwb3NpdGl2ZWx5KiBvciAqbmVnYXRpdmVseSogY29ycmVsYXRlZCB3aXRoIHNlYnVtZXRlciBzY29yZQ0KICArIFpvb3BhZ29teWNvdGEgc2hvdyBhIHNpZ25pZmljYW50IGVucmljaG1lbnQgb2YgYXNzb2NpYXRlZCBmZWF0dXJlcyB3aGljaCBhcmUgKnBvc2l0aXZlbHkqIGNvcnJlbGF0ZWQgd2l0aCBzZWJ1bWV0ZXIgc2NvcmUNCg0KVGhlc2UgYXJlIGRpZmZlcmVudCBwaHlsYSB0aGFuIGZvdW5kIGluIHRoZSBlbnJpY2htZW50IGFuYWx5c2lzIG9uIGZlYXR1cmVzLCB3aGljaCBpcyBhbm90aGVyIGluZGljYXRpb24gdGhhdCB0aGUgZW5yaWNobWVudCBtYXkgbm90IGJlIG1lYW5pbmdmdWwuIEluZGl2aWR1YWwgYXNzb2NpYXRpb25zIG1heSBvZiBjb3Vyc2Ugc3RpbGwgYmUgbWVhbmluZ2Z1bC4NCg0KIyBJbnRlcmVzdGluZyBtb2xlY3VsYXIgZmFtaWxpZXMNCg0KIyMgRmFtaWxpZXMgcG9zaXRpdmVseSBjb3JyZWxhdGVkIHdpdGggc2VidW1ldGVyIHNjb3JlDQoNCiMjIyBYOTQwMDI5DQoNCiFbWDk0MDAyOV0oOTQwMDI5IEZhdHR5IGFjaWQgbWV0aHlsIG9yIGV0aHlsIGVzdGVycy5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGQU1JTFlfSUQgPT0gIlg5NDAwMjkiKSAlPiUgDQogIHBpdm90X3dpZGVyKEZFQVRVUkVfSUQsIG5hbWVzX2Zyb20gPSBOQU1FLCB2YWx1ZXNfZnJvbSA9IHAudmFsdWUuZmRyLCBuYW1lc19zb3J0ID0gVCkgJT4lIA0KICBhcnJhbmdlKEZFQVRVUkVfSUQpDQpgYGANCg0KIVtYOTQwMDE3NF0oVHJlZSBYOTQwMDE3NC5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQwMDE3NCIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDAwMTc0IikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MDAyNTddKFRyZWUgWDk0MDAyNTcucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MDAyNTciKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQwMDI1NyIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDAwMzE2XShUcmVlIFg5NDAwMzE2LnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDAwMzE2IikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MDAzMTYiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQwMDkwNF0oVHJlZSBYOTQwMDkwNC5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQwMDkwNCIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDAwOTA0IikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MDExMjFdKFRyZWUgWDk0MDExMjEucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MDExMjEiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQwMTEyMSIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDAxMTIzXShUcmVlIFg5NDAxMTIzLnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDAxMTIzIikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MDExMjMiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQwMjE5Ml0oVHJlZSBYOTQwMjE5Mi5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQwMjE5MiIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDAyMTkyIikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MDI0MTddKFRyZWUgWDk0MDI0MTcucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MDI0MTciKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQwMjQxNyIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDAyNDk4XShUcmVlIFg5NDAyNDk4LnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDAyNDk4IikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MDI0OTgiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQwMjY3NF0oVHJlZSBYOTQwMjY3NC5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQwMjY3NCIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDAyNjc0IikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MDQzNjJdKFRyZWUgWDk0MDQzNjIucG5nKQ0KDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQwNDM2MiIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDA0MzYyIikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MDQ1ODFdKFRyZWUgWDk0MDQ1ODEucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MDQ1ODEiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQwNDU4MSIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDA3OTA5XShUcmVlIFg5NDA3OTA5LnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDA3OTA5IikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MDc5MDkiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQwOTA0OF0oVHJlZSBYOTQwOTA0OC5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQwOTA0OCIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDA5MDQ4IikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MjEwNDVdKFRyZWUgWDk0MjEwNDUucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MjEwNDUiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQyMTA0NSIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDIxNjU3XShUcmVlIFg5NDIxNjU3LnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDIxNjU3IikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MjE2NTciKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQyMzI2M10oVHJlZSBYOTQyMzI2My5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQyMzI2MyIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDIzMjYzIikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MjM2MjldKFRyZWUgWDk0MjM2MjkucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MjM2MjkiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQyMzYyOSIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDI2ODQ2XShUcmVlIFg5NDI2ODQ2LnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDI2ODQ2IikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MjY4NDYiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQzMDUzOF0oVHJlZSBYOTQzMDUzOC5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQzMDUzOCIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDMwNTM4IikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MzM0MDVdKFRyZWUgWDk0MzM0MDUucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MzM0MDUiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQzMzQwNSIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQojIyMgWDk1MDE5MA0KDQohW1g5NTAxOTBdKFg5NTAxOTAucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkFNSUxZX0lEID09ICJYOTUwMTkwIikgJT4lIA0KICBwaXZvdF93aWRlcihGRUFUVVJFX0lELCBuYW1lc19mcm9tID0gTkFNRSwgdmFsdWVzX2Zyb20gPSBwLnZhbHVlLmZkciwgbmFtZXNfc29ydCA9IFQpICU+JSANCiAgYXJyYW5nZShGRUFUVVJFX0lEKQ0KYGBgDQoNCiFbWDk1MDI2OTNdKFRyZWUgWDk1MDI2OTMucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk1MDI2OTMiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTUwMjY5MyIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQojIyBGYW1pbGllcyBuZWdhdGl2ZWx5IGNvcnJlbGF0ZWQgd2l0aCBzZWJ1bWV0ZXIgc2NvcmUNCg0KIyMjIFg5NDAwMDUNCg0KIVtYOTQwMDA1XSg5NDAwMDUucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkFNSUxZX0lEID09ICJYOTQwMDA1IikgJT4lIA0KICBwaXZvdF93aWRlcihGRUFUVVJFX0lELCBuYW1lc19mcm9tID0gTkFNRSwgdmFsdWVzX2Zyb20gPSBwLnZhbHVlLmZkciwgbmFtZXNfc29ydCA9IFQpICU+JSANCiAgYXJyYW5nZShGRUFUVVJFX0lEKQ0KYGBgDQoNCiFbWDk0MDE4MTRdKFRyZWUgWDk0MDE4MTQucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MDE4MTQiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQwMTgxNCIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDAyMjUyXShUcmVlIFg5NDAyMjUyLnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDAyMjUyIikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MDIyNTIiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQwMjM1Ml0oVHJlZSBYOTQwMjM1Mi5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQwMjM1MiIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDAyMzUyIikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MDI1NzldKFRyZWUgWDk0MDI1NzkucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MDI1NzkiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQwMjU3OSIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDAyOTg1XShUcmVlIFg5NDAyOTg1LnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDAyOTg1IikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MDI5ODUiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQwNDYwMl0oVHJlZSBYOTQwNDYwMi5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQwNDYwMiIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDA0NjAyIikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MDUzNzFdKFRyZWUgWDk0MDUzNzEucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MDUzNzEiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQwNTM3MSIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDExNDUwXShUcmVlIFg5NDExNDUwLnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDExNDUwIikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MTE0NTAiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQxMjI0MV0oVHJlZSBYOTQxMjI0MS5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQxMjI0MSIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDEyMjQxIikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MTI2MTRdKFRyZWUgWDk0MTI2MTQucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MTI2MTQiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQxMjYxNCIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDEzMzEzXShUcmVlIFg5NDEzMzEzLnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDEzMzEzIikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MTMzMTMiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQxMzQ1Nl0oVHJlZSBYOTQxMzQ1Ni5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQxMzQ1NiIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDEzNDU2IikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MjAzNjRdKFRyZWUgWDk0MjAzNjQucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MjAzNjQiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQyMDM2NCIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDIzNTQ1XShUcmVlIFg5NDIzNTQ1LnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDIzNTQ1IikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MjM1NDUiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQyNDExN10oVHJlZSBYOTQyNDExNy5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQyNDExNyIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDI0MTE3IikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0MjUxNzRdKFRyZWUgWDk0MjUxNzQucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0MjUxNzQiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQyNTE3NCIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NDI3MzgyXShUcmVlIFg5NDI3MzgyLnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NDI3MzgyIikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk0MjczODIiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTQyODIyMl0oVHJlZSBYOTQyODIyMi5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTQyODIyMiIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NDI4MjIyIikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk0Mjk1MjldKFRyZWUgWDk0Mjk1MjkucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk0Mjk1MjkiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTQyOTUyOSIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQojIyMgWDk1MDE2Nw0KDQohW1g5NTAxNjddKFg5NTAxNjcucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkFNSUxZX0lEID09ICJYOTUwMTY3IikgJT4lIA0KICBwaXZvdF93aWRlcihGRUFUVVJFX0lELCBuYW1lc19mcm9tID0gTkFNRSwgdmFsdWVzX2Zyb20gPSBwLnZhbHVlLmZkciwgbmFtZXNfc29ydCA9IFQpICU+JSANCiAgYXJyYW5nZShGRUFUVVJFX0lEKQ0KYGBgDQoNCiFbWDk1MDAzODldKFRyZWUgWDk1MDAzODkucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk1MDAzODkiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTUwMDM4OSIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NTAwMzkxXShUcmVlIFg5NTAwMzkxLnBuZykNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTUwMDM5MSIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NTAwMzkxIikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk1MDAzOTZdKFRyZWUgWDk1MDAzOTYucG5nKQ0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NTAwMzk2IikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk1MDAzOTYiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTUwMjMyN10oVHJlZSBYOTUwMjMyNy5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTUwMjMyNyIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NTAyMzI3IikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk1MDIzNTBdKFRyZWUgWDk1MDIzNTAucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk1MDIzNTAiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTUwMjM1MCIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQohW1g5NTA2MjM2XShUcmVlIFg5NTA2MjM2LnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NTA2MjM2IikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk1MDYyMzYiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIyMjIFg5NTA0NzcNCg0KIVtYOTUwNDc3XShYOTUwNDc3LnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZBTUlMWV9JRCA9PSAiWDk1MDQ3NyIpICU+JSANCiAgcGl2b3Rfd2lkZXIoRkVBVFVSRV9JRCwgbmFtZXNfZnJvbSA9IE5BTUUsIHZhbHVlc19mcm9tID0gcC52YWx1ZS5mZHIsIG5hbWVzX3NvcnQgPSBUKSAlPiUgDQogIGFycmFuZ2UoRkVBVFVSRV9JRCkNCmBgYA0KDQohW1g5NTAzMDM4XShUcmVlIFg5NTAzMDM4LnBuZykNCg0KYGBge3J9DQptYXNzdF9yZXN1bHRzICU+JSANCiAgZmlsdGVyKEZFQVRVUkVfSUQgPT0gIlg5NTAzMDM4IikgJT4lIA0KICBncm91cF9ieShGRUFUVVJFX0lEKSAlPiUgDQogIHN1bW1hcml6ZShQSFlMQSA9IE5BTUUgJT4lIHN0cl9jKGNvbGxhcHNlID0gIiwgIikpICU+JSANCiAgYXMubGlzdCgpDQoNCmZlYXR1cmVfaW5mbyAlPiUgDQogIGZpbHRlcihNRVRfQ0hFTV9OTyA9PSAiWDk1MDMwMzgiKSAlPiUgDQogIHNlbGVjdChNRVRfQ0hFTV9OTywgc3RhcnRzX3dpdGgoIkNvbnNfIiksIGBDQU5fYWxsIGNsYXNzaWZpY2F0aW9uc2ApICU+JSANCiAgYXMubGlzdCgpDQpgYGANCg0KIVtYOTUwMzE0Ml0oVHJlZSBYOTUwMzE0Mi5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTUwMzE0MiIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NTAzMTQyIikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiMjIyBYOTcwMDM0DQoNCiFbWDk3MDAzNF0oWDk3MDAzNC5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGQU1JTFlfSUQgPT0gIlg5NzAwMzQiKSAlPiUgDQogIHBpdm90X3dpZGVyKEZFQVRVUkVfSUQsIG5hbWVzX2Zyb20gPSBOQU1FLCB2YWx1ZXNfZnJvbSA9IHAudmFsdWUuZmRyLCBuYW1lc19zb3J0ID0gVCkgJT4lIA0KICBhcnJhbmdlKEZFQVRVUkVfSUQpDQpgYGANCg0KIVtYOTcwMTg2NF0oVHJlZSBYOTcwMTg2NC5wbmcpDQoNCmBgYHtyfQ0KbWFzc3RfcmVzdWx0cyAlPiUgDQogIGZpbHRlcihGRUFUVVJFX0lEID09ICJYOTcwMTg2NCIpICU+JSANCiAgZ3JvdXBfYnkoRkVBVFVSRV9JRCkgJT4lIA0KICBzdW1tYXJpemUoUEhZTEEgPSBOQU1FICU+JSBzdHJfYyhjb2xsYXBzZSA9ICIsICIpKSAlPiUgDQogIGFzLmxpc3QoKQ0KDQpmZWF0dXJlX2luZm8gJT4lIA0KICBmaWx0ZXIoTUVUX0NIRU1fTk8gPT0gIlg5NzAxODY0IikgJT4lIA0KICBzZWxlY3QoTUVUX0NIRU1fTk8sIHN0YXJ0c193aXRoKCJDb25zXyIpLCBgQ0FOX2FsbCBjbGFzc2lmaWNhdGlvbnNgKSAlPiUgDQogIGFzLmxpc3QoKQ0KYGBgDQoNCiFbWDk3MDczODRdKFRyZWUgWDk3MDczODQucG5nKQ0KDQpgYGB7cn0NCm1hc3N0X3Jlc3VsdHMgJT4lIA0KICBmaWx0ZXIoRkVBVFVSRV9JRCA9PSAiWDk3MDczODQiKSAlPiUgDQogIGdyb3VwX2J5KEZFQVRVUkVfSUQpICU+JSANCiAgc3VtbWFyaXplKFBIWUxBID0gTkFNRSAlPiUgc3RyX2MoY29sbGFwc2UgPSAiLCAiKSkgJT4lIA0KICBhcy5saXN0KCkNCg0KZmVhdHVyZV9pbmZvICU+JSANCiAgZmlsdGVyKE1FVF9DSEVNX05PID09ICJYOTcwNzM4NCIpICU+JSANCiAgc2VsZWN0KE1FVF9DSEVNX05PLCBzdGFydHNfd2l0aCgiQ29uc18iKSwgYENBTl9hbGwgY2xhc3NpZmljYXRpb25zYCkgJT4lIA0KICBhcy5saXN0KCkNCmBgYA0KDQojIFNlc3Npb24gaW5mbw0KDQpgYGB7cn0NCnNlc3Npb25JbmZvKCkNCmBgYA0K